//============================================================================================
/**
 * @file	pkthln_steal.c
 * @brief	フラッグ
 * @author	Nozomu Saito
 */
//============================================================================================

#include "pkthln_steal.h"
#include "pkthln_steal_local.h"
#include "../../pkthln_obj_common.h"
#include "../../poke_clact.h"
#include "../pkthln_clact.h"
#include "../pkthln_act_def.h"

#include "system/snd_tool.h"
#include "system/wipe.h"
#include "system/render_oam.h"
#include "system/fontproc.h"
#include "gflib/touchpanel.h"

#include "../../pkthln_comm_pack.h"
#include "../../poke_clact_move.h"

#include "../event_se_def.h"

#include "system/arc_util.h"

#include "steal_comm.h"
#include "steal_obj_pri.h"

#include "../../cmn_res.h"

#include "pkthln_steal_sub.h"

#include "steal_ai.h"

//成績作成用
#include "system/msgdata_util.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_pokethlon.h"

#include "../pkthln_evt_info.naix"
#include "pkthev_steal.naix"
#include "communication/wm_icon.h"

//同期待ち
#include "../../pkthln_frame_seq_def.h"	//for	FRAME_SEQ_CALLBACK_WAIT

// 構造体が想定のサイズとなっているかチェック
#ifdef PM_DEBUG
#ifdef _NITRO
SDK_COMPILER_ASSERT(sizeof(STL_PARENT_DATA) == 36);
#endif
extern DEBUG_PKTHLN_WORK DebugPkthlnWk;
#endif		//PM_DEBUG

//デバッグ機能
#ifdef PM_DEBUG
///#define DEBUG_HIT_CHECK_IGNORE	//障害物当たり判定無視
///#define DEBUG_TIME_DEC_NONE		//時間減らない
///#define DEBUG_MIN_TIME			//デバッグ短縮時間
#endif

#define STL_HEAP_SIZE	(0x68000)

#define STL_EVENT_POKE_NUM	(ENTRY_MAX*ENTRY_MEMBER_NUM_MAX)
#define SUB_ACT_MAX		(ENTRY_MEMBER_NUM_MAX*(6+PT_ACT_NUM) + 2 + 1)
//↑（アイコン+マーカー+ステート+吹き出し+数字+旗+得点取得2）*表示アイコン4 + ポケグラ2 + 時計1
#define MAIN_ACT_MAX	(1+1+(STL_EVENT_POKE_NUM*(5+PT_ACT_NUM+1))+OBST_NUM_MAX+(PARASOL_NUM_MAX*2)+4+FLAG_DISP_MAX*2 + ENTRY_MAX)
//↑カウントダウン+ラストカウント+チーム数*(ポケ+マーカ+影+ステート+煙+得点取得2+旗取得)+障害物*20+パラソル10上下+ヒットエフェクト4+(旗・煙)*5 + ペン3
#define ACT_MAX		(MAIN_ACT_MAX + SUB_ACT_MAX)
#define SUB_DISP_PAL_NUM	(3+2+2)		//アイコンパレット3+ポケグラｘ2+OBJ2
#define STL_MAIN_OBJ_PALETTE_NUM	(2)			//OBJ

#define STL_EVENT_OBJ_NUM	(STL_EVENT_POKE_NUM + ACT_MAX )
#define STL_EVENT_PAL_NUM	(STL_EVENT_POKE_NUM + 1 + \
		STL_MAIN_OBJ_PALETTE_NUM + SUB_DISP_PAL_NUM)	//ポケ12+共有リソース+メイン画面+サブ画面

#define START_POKE_POS_X	(128)
#define START_POKE_POS_Y	(96)
#define START_POKE_MARGINE	( 32 )

#define PCLACT_TCB_PRIORITY	(0)

#define TOUCH_TIME_MAX	(255)
#define TOUCH_TIME_ACCEL	(30)
#define TOUCH_TIME_BRAKE	(30)

#define ACCEL_DIV	(8.0)
#define DECEL_COEF	(0.1)		//減速係数

#define DISP_X_MIN	(-32)
#define DISP_X_MAX	(256+32)
#define DISP_Y_MIN	(-32)
#define DISP_Y_MAX	(192+32)

#define CHG_BTN_W	(64)
#define CHG_BTN_H	(32)

#define POKE_MOVE_COUNT	(32)
#define DEMO_MOVE_Y		(8)

#ifdef DEBUG_MIN_TIME
#define GAME_TIME		(30)		//デバッグ短縮ゲーム時間
#else
#define GAME_TIME		(60*30)		//ゲーム時間1分
#endif

#define HIT_EFFECT_NUM	(4)
#define SND_EFFECT_NUM	(4)

#define HIT_FRAME_DMG		(6)		//ヒット後の硬直時間(あたられた方)
#define HIT_FRAME_ATK	(18)		//ヒット後の硬直時間(あたった方)

#define PT_GET_MARGINE	(4)
#define PT_GET_HOLD_TIME	(10)

//ＢＭＰ関連
#define	REC_FONT_PAL	(15)
#define WIN_CGX_BASE	(1)
#define WIN_REC_CGX	(WIN_CGX_BASE)
#define REC_BG	(GF_BGL_FRAME3_M)

#define	COL_N_WHITE	( GF_PRINTCOLOR_MAKE( 15, 14, 0 ) )		// フォントカラー：白

#define GAME_MAX_SPEED	(11)		//ゲーム内最大速度

#define START_SCRL_X_OFS	(208)		//ドット
#define START_SCRL_Y_OFS	(416)		//ドット

#define CHANGE_Y_LIMIT_MAX	(408)		//ドット

#define FLAG_RANGE	(8)

#define FLAG_CONT_MAX	(20)		//旗管理最大
#define FLAG_TAKE_MAX	(9)			//持てる旗最大
#define STEAL_FLAG_NUM	(2)			//奪う旗の数

#define MAP_TYPE_MAX	(20)

#define SND_EFF_LEN		(1*FX32_ONE)

#define BG_ANM_CHAR_TRANS_OFS	(0x1800)	//ＢＧキャラ転送アニメキャラオフセット グラフィックデータ依存
#define BG_ANM_CHAR_TRANS_SIZE	(0x800)		//転送キャラサイズ（64キャラ分）
#define TRNS_ANM_TIMING		(4)		//転送タイミング
#define TRNS_ANM_NUM		(6)		//転送パターン数

#define SE_PLAYER_MINE		(PLAYER_SE_1)
#define SE_PLAYER_OTHERS	(PLAYER_SE_2)

#define DEC_SP	(-0.3)		//跳ね返り係数

#define DISP_HEIGHT	(256)

#define POINT_MAX	(999)	//競技最大獲得点数


//デバッグ
#ifdef PM_DEBUG
//#define DBG_STC_CRS		//有効でコース固定
static const u8 DbgCrs = 0;		//コースインデックス
#endif

typedef enum {
	CHILD_CHG_NONE = 0,
	CHILD_CHG_DOWN_END,
	CHILD_CHG_UP_END,
}CHILD_CHG_STATE;

typedef enum {
	PRI_OFS_FLG_GET = 0,
	PRI_OFS_OBST = 1,
	PRI_OFS_SND = 2,
	PRI_OFS_STATE = 3,
	PRI_OFS_POKE = 4, //ポケ・シャドー・マーカーが連番
	PRI_OFS_POLE = 7,
	PRI_OFS_FLG_AP = 8,
	PRI_OFS_FLG = 9,
};

typedef struct STL_PARAM_tag
{
	int Power[5];
	int Accel1[5];
	int Accel2[5];
	int Panic[5];
	int Speed[5];
}STL_PARAM;

typedef struct STL_OBST_tag
{
	BOOL Valid;
	PKTHLN_ACT_PTR	ActPtr;
	u16 X;
	u16	Y;
}STL_OBST;

typedef struct STL_PARASOL_tag
{
	BOOL Valid;
	PKTHLN_ACT_PTR	PoleActPtr;
	PKTHLN_ACT_PTR	RoofActPtr;
	u16 X;
	u16	Y;
}STL_PARASOL;

typedef struct OBJ_POS_tag
{
	u16 x;
	u16 y;
}OBJ_POS;

typedef struct FLAG_DATA_tag
{
	STL_FLAG	Flag[FLAG_DISP_MAX];
	OBJ_POS		FlgPos[FLAG_CONT_MAX];
	u16 		FlgPosIdx;
	u16 		DispFlgNum;
}FLAG_DATA;

typedef struct PKTHLN_STL_tag
{
	GF_BGL_INI *bgl;
	GF_BGL_BMPWIN	Win;			// BMPウィンドウデータ
	int HeapID;

	void *BgCharData;
	NNSG2dCharacterData *TransCharData;
	//アクター
	PKTHLN_CLACT_CNT_PTR ActCntPtr;

	STL_POKE	Poke[ENTRY_MEMBER_NUM_MAX];

	TP_STATE	TpState[ENTRY_MEMBER_NUM_MAX];		//親が使う
	BOOL HoldPoke[ENTRY_MEMBER_NUM_MAX];			//親が使う

	CMN_RES_CNT_PTR	CmnResCntPtr;
	POKE_ACT_CNT_PTR PokeActCntPtr;
	//ヒット
	PKTHLN_ACT_PTR	HitActPtr[HIT_EFFECT_NUM];
	//砂煙
	PKTHLN_ACT_PTR	SndActPtr[SND_EFFECT_NUM];

	STEAL_AI_CONT_PTR AICntPtr;
	STL_SUB_CNT_PTR SubDispCntPtr;

	//障害物データ
	int ParentMapIdx;
	int ChildMapIdx;
	STL_OBST	Obst[OBST_NUM_MAX];
	STL_PARASOL Parasol[PARASOL_NUM_MAX];

	u16 CommTime;			//通信する時間データ
	u8 EndFlg;
	u8 StartCount;

	u8 Brake;
	u8 TrnsAnmIdx;
	u8 TrnsCount;
	u8  LocalFlagIdx[FLAG_DISP_MAX];		//演出用

	u8 HitEffIdx;
	u8 HitEff;
	u8 SndEffIdx;
	u8 SndEff;
	u16 HitEffY;
	u16 HitEffX;
	u16 SndEffY;
	u16 SndEffX;
	int HitX[HIT_EFFECT_NUM];
	int HitY[HIT_EFFECT_NUM];
	int SndX[SND_EFFECT_NUM];
	int SndY[SND_EFFECT_NUM];

	FLAG_DATA FlagData;
	OBJ_POS ObstPos[OBST_NUM_MAX];
	OBJ_POS ParasolPos[OBST_NUM_MAX];

	u8 SeFlg[ENTRY_MEMBER_NUM_MAX];

}PKTHLN_STL;

typedef struct SEG_tag
{
	Vec2DS32 Srt;
	Vec2DS32 End;
}SEG;

typedef struct S_OBST_HIT_DATA_tag
{
	Vec2DS32 Vrt[4];
	SEG Seg[4];
}S_OBST_HIT_DATA;

static void SetVramBank(void);
static void BgInit(GF_BGL_INI * ini);
static void SetGraphic(PKTHLN_STL_PTR ptr);
static void SetObj( PKTHLN_CLACT_CNT_PTR pActCntPtr);
static void SetAct( PKTHLN_STL_PTR ptr, PKTHLN_CLACT_CNT_PTR pActCntPtr);

static BOOL STL_Func_Phase0(PKTHLN_PTR work, u8 *seq);
static BOOL STL_Func_Phase1(PKTHLN_PTR work, u8 *seq);
static BOOL STL_Func_Phase2(PKTHLN_PTR work, u8 *seq);

static void SetCommInfo(PKTHLN_STL_PTR ptr, STL_PARENT_DATA *parent);
static void CommMain(PKTHLN_PTR work);
static BOOL ControlMain(PKTHLN_PTR work);
static void SetDraw(PKTHLN_PTR work);

static BOOL CheckPokeTouch(PKTHLN_STL_PTR ptr, const u8 inNetID, const u16 inX, const u16 inY);
static void MovePoke(PKTHLN_PTR work);
static void MovePokeHitFrame(PKTHLN_PTR work, PKTHLN_STL_PTR ptr, STL_POKE *stl_poke);
static void CalcPokeDispPos(PKTHLN_PTR work,
							const u8 inMyNetID,
							STL_POKE *inPokeList,
							COMM_EVENT_COMMON_DATA *commData);
static void CalcObstDispPos(PKTHLN_STL_PTR ptr, const int inPokeX, const int inPokeY);
static void CalcParasolDispPos(PKTHLN_STL_PTR ptr, const int inPokeX, const int inPokeY);
static void CalcFlagDispPos(PKTHLN_STL_PTR ptr, STL_PARENT_DATA *parent,
								const int inPokeX, const int inPokeY);
static void ChangeDemo(	STL_SUB_CNT_PTR sub_ptr, STL_POKE *stl_poke,
						const STL_PARENT_DATA *inParent,
						const u8 inNetID, const u8 inStlPokeIdx,
						STL_CHILD_DATA *outChildData,
						const BOOL inIsParent, const BOOL inReqSubDemo, const BOOL inIsNPC);
static void SetPokeParam(	PKTHLN_PTR work, const STL_PARAM *inData,
							const u8 inNetID, const u8 inIdx, STL_POKE *outPoke);
static void MakeObstList(PKTHLN_STL_PTR ptr, const fx32 inX, const fx32 inY,
		OBJ_POS **outObstList, u8 *outObstNum);
static void MakeHitData( const int inRange, const OBJ_POS *inObstData, S_OBST_HIT_DATA *outHitData);
static u16 HitCheckObst(PKTHLN_STL_PTR ptr, const HIT_RC inHitRc, const int inRange,
		const VecFx32 *inSrt, const VecFx32 *inEnd, VecFx32 *outVec);

static fx32 CalcT(const VecFx32 *inSrt, const VecFx32 *inEnd,
		const VecFx32 *inVrt , const fx32 inC);

static float GetMaxSpeed( STL_POKE *poke, const u8 inStlPokeIdx );
static void AddSpeedVec(const VecFx32 *inSrcVec, const VecFx32 *inAddVec, VecFx32 *outDstVec);
static BOOL HitCheckPoke(PKTHLN_PTR work, STL_POKE*	pPokeList, VecFx32 *outVec);
static void SetStateActPos(	const PKTHPOKE_PARAM *inParam,
							const VecFx32 *inSdwPos,
							PKTHLN_ACT_PTR pStateActPtr );
static void SetObjPriority(PKTHLN_STL_PTR ptr);
static void SetPokePriority(STL_POKE *poke, const int inY);
static void SetFlagPriority(STL_FLAG *flag, const int inY);
static void SetEffPriority(PKTHLN_STL_PTR ptr);

static void CreateBmpWin( PKTHLN_STL_PTR ptr );
static void SetRecordStr(PKTHLN_STL_PTR ptr, const int inRecord);

//旗データ初期化
static void InitFlagData(PKTHLN_STL_PTR ptr);
//旗アクター座標インデックスのインクリメント
static void IncFlagPosIdx(FLAG_DATA * pFlagData);
//旗アクターセット
static void SetFlag(FLAG_DATA * pFlagData);
//旗ジェネレータ
static void GenerateFlag(PKTHLN_STL_PTR ptr);
//旗取得
static BOOL GetFlag(FLAG_DATA *pFlagData, STL_POKE *ioPoke, u8 *outSE);
//サークルヒット判定
static BOOL HitCheckCircle(const VecFx32 *inVec1, const VecFx32 *inVec2,
		const fx32 inRange1, const fx32 inRange2);
//方向ベクトルからポケモンの向きを計算
static u8 CalcDir(const VecFx32 *inVec);
static BOOL CheckPanicHit(PKTHLN_PTR work, STL_POKE* poke1, STL_POKE* poke2);
static BOOL CheckGoal(STL_POKE *inPoke);
static u8 CalcPointByGetFlag(const u8 inFlagNum);
static int GetOBJPriorityByY(const int inY);

static void TransAnmMain(PKTHLN_STL_PTR ptr);

static void PlaySeDispCheck(const int inX, const int inY, const int inSE, const BOOL inMine);

static void RecCallBack(PKTHLN_PTR work);

PKTHLN_FUNC StlFuncTbl[] = {
	STL_Func_Phase0,
	STL_Func_Phase1,
	STL_Func_Phase2,
};

enum {
	STL_SEQ_PHASE0,
	STL_SEQ_PHASE1,
	STL_SEQ_PHASE2,
};

#ifdef PM_DEBUG
static u8 debug_print = 0;
#endif

//--------------------------------------------------------------------------------------------
/**
 * 初期化関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
PTH_RC PE_STL_InitFunc(PKTHLN_PTR work, void *pParam)
{
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);
	u8 seq = PTFrame_GetSubSeq(work);
	switch(seq){
	case 0:
		{
			int heap_id;
			sys_CreateHeap( HEAPID_POKETHLON, HEAPID_PT_STEAL, STL_HEAP_SIZE );
			heap_id = HEAPID_PT_STEAL;
			sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
			sys_HBlankIntrSet( NULL,NULL );		// HBlankセット

			GF_Disp_GX_VisibleControlInit();
			GF_Disp_GXS_VisibleControlInit();
			GX_SetVisiblePlane( 0 );
			GXS_SetVisiblePlane( 0 );

			//VRAMバンク割り当て
			SetVramBank();
			//アプリケーションメモリー
			ptr = PTFrame_AllocEventWork(work, sizeof(PKTHLN_STL));
			MI_CpuClear8( ptr, sizeof(PKTHLN_STL));

			//BGLアロケーション
			ptr->bgl = GF_BGL_BglIniAlloc(heap_id);

			//競技アプリ内共有データポインタのセット
			PTFrame_SetEvtShareDataPtr(work, &ptr->ParentMapIdx, &ptr->ChildMapIdx, sizeof(int) );

			//レコード表示ＢＧのセット
			PTFrame_SetRecBGMask(work, GX_PLANEMASK_BG3);

			{
				CHAR_MANAGER_MAKE cm;
				cm.CharDataNum = STL_EVENT_OBJ_NUM;
				cm.VramTransAreaMain = 256*1024;
				cm.VramTransAreaSub = 16*1024;
				cm.heap = heap_id;

				//キャラ・パレットマネージャ初期化
				PKTHLN_OBJ_COMMON_InitCharPlttManager(	&cm,
														STL_EVENT_PAL_NUM,
														heap_id,
														GX_OBJVRAMMODE_CHAR_1D_256K,
														GX_OBJVRAMMODE_CHAR_1D_32K);
			}

			// OAMマネージャーの初期化
			NNS_G2dInitOamManagerModule();

			// 共有OAMマネージャ作成
			// レンダラ用OAMマネージャ作成
			// ここで作成したOAMマネージャをみんなで共有する
			REND_OAMInit(
					0, 126,		// メイン画面OAM管理領域
					0, 32,		// メイン画面アフィン管理領域
					0, 126,		// サブ画面OAM管理領域
					0, 32,		// サブ画面アフィン管理領域
					heap_id);
			ptr->HeapID = heap_id;
		}

		//タッチフォントロード
		FontProc_LoadFont(FONT_TOUCH, ptr->HeapID);

		BgInit(ptr->bgl);

		//BMP
		CreateBmpWin(ptr);

		//下画面をメインにする
		sys.disp3DSW = DISP_3D_TO_SUB;
		GF_Disp_DispSelect();

		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 1:
		ptr->SubDispCntPtr = StlSub_Init( ptr->HeapID, ptr->bgl, work);
		ptr->AICntPtr = StealAI_Init(ptr->HeapID,
				ENTRY_MEMBER_NUM_MAX-PTFrame_GetPlayerNum(work), PTFrame_GetGameType(work));
		ptr->CmnResCntPtr = CmnRes_Init( ptr->HeapID,
				CMN_RES_ALL_BIT|CMN_RES_F2X2SUB_BIT|CMN_RES_F4X4_BIT|CMN_RES_PEN_M_BIT, NNS_G2D_VRAM_TYPE_2DMAIN );

		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 2:
		{
			int i;
			CLACT_WORK_PTR act_ptr;
			PKTHLN_ACT_SETUP_PRM param = {
				ACT_MAX,4,{4,4,4,4}
			};
			ptr->ActCntPtr = PkthlnClAct_Init(ptr->HeapID, &param);

			//上下画面幅設定
			PkthlnClAct_SetDispDistance(ptr->ActCntPtr,
										0, 0,
										0, SUB_DISP_DISTANCE );
			//ポケモンアクター
			ptr->PokeActCntPtr = PokeAct_Init( ptr->HeapID, STL_EVENT_POKE_NUM, PRI_POKE_MINE,
									  ptr->CmnResCntPtr, PkthlnClAct_GetClActSetAdr(ptr->ActCntPtr) );

			PkthlnClAct_SetResObjCode(ptr->ActCntPtr, 0, RES_CODE_STL_SUB);
			PkthlnClAct_SetResObjCode(ptr->ActCntPtr, 1, RES_CODE_STL_TRNS_POKE1);
			PkthlnClAct_SetResObjCode(ptr->ActCntPtr, 2, RES_CODE_STL_TRNS_POKE2);
			PkthlnClAct_SetResObjCode(ptr->ActCntPtr, 3, RES_CODE_STL_MAIN);
			//
///			PushSub_SetTrnsPokeRes(ptr->ActCntPtr, ptr->SubDispCntPtr);
			//サブ
			StlSub_SetObj( ptr->SubDispCntPtr, ptr->ActCntPtr );
			//メイン
			SetObj(ptr->ActCntPtr);
			//トランス
			PkthlnClAct_Trans(ptr->ActCntPtr);


			//カウントダウンアクター
			{
				CLACT_WORK_PTR	*act_adr;
				act_adr = PTFrame_SetCountDown( work, 0, ptr->CmnResCntPtr, ptr->ActCntPtr );
				//プライオリティセット
				CLACT_DrawPriorityChg( *act_adr, PRI_COUNT );
			}

			//メイン画面ＯＢＪ
			SetAct( ptr, ptr->ActCntPtr);

			StlSub_SetPokeAct( ptr->SubDispCntPtr, ptr->ActCntPtr, ptr->CmnResCntPtr );

		}
		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 3:
		{
			int i;
			MONS_INFO info[STL_EVENT_POKE_NUM];
			PCLACT_SET_PARAM param;
			ICON_INFO icon_info[STL_EVENT_POKE_NUM];

			for(i=0;i<STL_EVENT_POKE_NUM;i++){
				PTFrame_SetMonsInfo(work, i/ENTRY_MAX, i%ENTRY_MAX, &info[i]);

				param.ShadowPos[i] =
					PTFrame_GetPokeShdwPosType(PTFrame_GetPkthlnParam(work, i/ENTRY_MAX, i%ENTRY_MAX));

				//ポケモンアイコン情報取得
				icon_info[i].MonsNo = info[i].MonsNo;
				icon_info[i].Form = info[i].Form;
			}

			//ポケモンアイコン
			StlSub_SetupPokeIcon( ptr->SubDispCntPtr, icon_info );
			//ポケグラのセット
			{
				u8 net_id = PTFrameGetCurrentID(work);
				StlSub_SetupPokeGraphic(ptr->SubDispCntPtr, &info[net_id*ENTRY_MAX]);
			}
			//控えポケのグラフィックトランス
			StlSub_TransPokeGra( ptr->SubDispCntPtr, 0, 1);
			StlSub_TransPokeGra( ptr->SubDispCntPtr, 1, 2);

			param.Quick = 0;
			param.BGPriority = 2;
			param.Trans = 0;
			param.ResVramType = NNS_G2D_VRAM_TYPE_2DMAIN;
			param.DrawArea = NNS_G2D_VRAM_TYPE_2DMAIN;

			PokeAct_SetPokeActor(	ptr->PokeActCntPtr, STL_EVENT_POKE_NUM,
									info, &param,
									PCLACT_TCB_PRIORITY,
									0 );

			//サブ画面ＯＢＪプライオリティセット
			StlSub_SetPriority( ptr->SubDispCntPtr, PTFrameGetCurrentID(work));

		}
		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 4:
		if ( PokeAct_CheckActSetTask(ptr->PokeActCntPtr) ){
			PEN_POS	pen_pos;
			EVT_HIT_DATA hit_data;
			int i;
			int my_net_id;

			my_net_id = PTFrameGetCurrentID(work);

			PTFrame_SetDefaultVBlankFunc(ptr->bgl);	// VBlankセット
			//描画を許可
			PTFrame_SetDraw(work, TRUE);

			ArchiveDataLoad(hit_data.Data, ARC_PKTHEVT_PARAM, NARC_pkthln_evt_info_steal_hit_bin);
			//ポケセルアクター
			for (i=0;i<STL_EVENT_POKE_NUM;i++){
				POKE_ACT_PTR poke_ptr = PokeAct_GetPokeActPtr(ptr->PokeActCntPtr, i);
				//各チームの最初のエントリーポケだけ表示
				if (i%ENTRY_MAX == 0){
					PokeAct_DispCnt(poke_ptr, 1);	//表示
				}

				//あたり判定データセット
				{
					HIT_TYPE hit_type;
					hit_type = PTFrame_GetPokeHitType(PTFrame_GetPkthlnParam(work, i/ENTRY_MAX, i%ENTRY_MAX));
					PokeAct_SetHitData(poke_ptr, hit_data.Data[hit_type-1].Ofs, hit_data.Data[hit_type-1].Range);
				}

				//ポケモン初期位置
				{
					STL_POKE *stl_poke;
					POKE_ACT_PTR poke_ptr = PokeAct_GetPokeActPtr(ptr->PokeActCntPtr, i);

					stl_poke = &ptr->Poke[i/ENTRY_MAX];
					stl_poke->PokeActPtr[i%ENTRY_MAX] = poke_ptr;

					//位置決定
					{
						int sx,sy;
						int range;
						//影の位置
						sx = START_POKE_POS_X + (START_POKE_MARGINE * (i/ENTRY_MAX));
						sy = START_POKE_POS_Y;

						stl_poke->Dir = POKE_DIR_UP;
						//向きセット
						PokeAct_SetDir(poke_ptr, POKE_DIR_UP);
						//アクター位置セット
						PokeAct_SetPosShadow(poke_ptr, sx, sy);

						//タッチ半径セット
						range = PTFrame_GetPokeTouchRange();
						PokeAct_SetTouchRange(poke_ptr, range);

						stl_poke->Pos.x = ( START_SCRL_X_OFS + START_POKE_MARGINE*(i/ENTRY_MAX) ) * FX32_ONE;
						stl_poke->Pos.y = START_SCRL_Y_OFS * FX32_ONE;

						//ポケモンアクターの影・マーカーのプライオリティオフセット変更
						PokeAct_ChgPriorityOfs(poke_ptr, 3000);
						//↑どんなものより下になるように大きい値を入れておく(とりうる値は、DISP_HEIGHT*8なのでそれより大きい値)

						//自分の先頭ポケのペン表示座標を保存
						if ( ((i/ENTRY_MAX)==my_net_id)&&((i%ENTRY_MAX)==0) ){
							int tx,ty;
							//タッチ中心座標取得
							PokeAct_GetTouchPosByShadowPos(poke_ptr, sx, sy, &tx, &ty);
							pen_pos.X = START_POKE_POS_X;
							pen_pos.Y = ty;
						}

					}//位置決定
				} //ポケモン初期位置
			}	//end for

			{
				STL_PARAM data;
				int i;
				STL_POKE *stl_poke;
				ArchiveDataLoad(&data, ARC_PKTHEVT_PARAM, NARC_pkthln_evt_info_steal_bin);
#if 0
				{
					int m;
					for(m=0;m<5;m++){
						OS_Printf("run_prm:%d,%d,%d,%d,%d,%d,%d,%d\n",
								data.Power[m], data.Stamina[m], data.Accel1[m], data.Accel2[m], data.Panic[m],
								data.Speed[m], data.SpeedLow[m], data.SpeedMat[m]);
					}
				}
#endif
				//ゲーム時間セット
				ptr->CommTime = GAME_TIME;

				//時間表示
				StlSub_DispTime(ptr->SubDispCntPtr, ptr->CommTime);
				//旗データ初期化
				InitFlagData(ptr);

				for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
					int j;
					//親の判定データ初期化
					ptr->HoldPoke[i] = FALSE;
					//パラメータ格納
					for(j=0;j<ENTRY_MAX;j++){
						stl_poke = &ptr->Poke[i];
						SetPokeParam(work, &data, i, j, stl_poke);
					}
					if (PTFrameGetCurrentID(work) == COMM_PARENT_ID){
						//AI用にポケモンデータをセットアップ
						StealAI_SetupPokeInfo( ptr->AICntPtr, i, stl_poke );
					}
					//ネットＩＤ保存
					ptr->Poke[i].NetID = i;
				}
				//親のとき、初回送信データを作成
				if (PTFrameGetCurrentID(work) == COMM_PARENT_ID){
					COMM_EVENT_COMMON_DATA *data;
					data = PTFrame_GetEvtComCmnData(work);
					SetCommInfo(ptr,
							PKTHLN_CommPack_GetData(&data->SendShareData));
				}
			}

			//ペン表示
			PTFrame_SetPen( work, 0, ptr->CmnResCntPtr, ptr->ActCntPtr,
						    NNS_G2D_VRAM_TYPE_2DMAIN, 1,  &pen_pos);

			SetGraphic(ptr);

			//ＯＢＪの表示
			GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// MAIN DISP OBJ ON
			GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// SUB DISP OBJ ON

			//BGスクロール
			{
				STL_POKE *stl_poke;
				int x_ofs,y_ofs;
				stl_poke = &ptr->Poke[my_net_id];

				x_ofs = stl_poke->Pos.x / FX32_ONE;
				x_ofs -= START_POKE_POS_X;
				y_ofs = stl_poke->Pos.y / FX32_ONE;
				y_ofs -= START_POKE_POS_Y;
				GF_BGL_ScrollReq( ptr->bgl, GF_BGL_FRAME0_M, GF_BGL_SCROLL_X_SET, x_ofs );
				GF_BGL_ScrollReq( ptr->bgl, GF_BGL_FRAME0_M, GF_BGL_SCROLL_Y_SET, y_ofs );
			}

			//通信アイコン
			WirelessIconEasyPokethlon( NNS_G2D_VRAM_TYPE_2DMAIN );

			//次のシーケンスへ
			PTFrame_IncSubSeq(work);
		}
		break;
	case 5:
		//マップデータ決定
		if ( PTFrameGetCurrentID(work) == COMM_PARENT_ID ){
			ptr->ParentMapIdx = gf_rand()%MAP_TYPE_MAX;
#ifdef PM_DEBUG
#ifdef DBG_STC_CRS
			ptr->ParentMapIdx = DbgCrs;
#endif
#endif
			OS_Printf("コースは%d\n",ptr->ParentMapIdx);
		}
		//次のシーケンスへ
		PTFrame_IncSubSeq(work);
		break;
	case 6:
		return PTH_RC_END;
		break;
	}
	return PTH_RC_LOOP;
}
//--------------------------------------------------------------------------------------------
/**
 * 描画関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
BOOL PE_STL_DrawFunc(PKTHLN_PTR work, void *pParam)
{
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	PkthlnClAct_Draw(ptr->ActCntPtr);
	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * 競技結果計算関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
BOOL PE_STL_ResultFunc(PKTHLN_PTR work, void *pParam)
{
	int i,j;
	RSLT_PTR result_ptr;

	OS_Printf("競技結果データ作成\n");

	result_ptr = PTFrame_GetResultPtr(work);
	RSLT_Setup( result_ptr );

	for( i=0;i<ENTRY_MEMBER_NUM_MAX;i++ ){
		int rec;
		rec = PTFrame_GetEvtResult(work, i);
		RSLT_SetResult(	work, result_ptr,
							i, rec,
							0, 3, msg_pkthln_new_record02 );
	}

	//ソート
	RSLT_Sort(result_ptr, SORT_REC_LARGE);
	//得点セット
	PTC_CalcPoint(result_ptr, PKTHLN_EVT_STEAL);

	//総得点に加算
	RSLT_AddTotalScore(result_ptr);

	//競技得点セット
	RSLT_SetEvtScore(result_ptr, PKTHLN_EVT_STEAL);

	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * 終了関数
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*pParam		パラメータ
 *
 * @return	TRUE
 */
//--------------------------------------------------------------------------------------------
BOOL PE_STL_EndFunc(PKTHLN_PTR work, void *pParam)
{
	int i;
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	// 通信アイコン撤去
	WirelessIconEasyEnd();

	sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
	sys_HBlankIntrSet( NULL,NULL );		// HBlankセット

	//共有データクリア
	PTFrame_ClearEvtShareDataPtr(work);

	//転送キャラデータ解放
	sys_FreeMemoryEz(ptr->BgCharData);

	//スクリーンアーカイブ解放
///	sys_FreeMemoryEz(ptr->MainBgArc);
	//BG削除
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME0_M );
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME3_M );
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME0_S );
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME1_S );
	GF_BGL_BGControlExit(ptr->bgl, GF_BGL_FRAME2_S );

	//BMP
	GF_BGL_BmpWinDel( &ptr->Win );

	//BGL解放
	sys_FreeMemoryEz(ptr->bgl);

	//アクター解放
	PkthlnClAct_Free(ptr->ActCntPtr);

	//ポケアクターコントローラ解放
	PokeAct_Free(ptr->PokeActCntPtr);
	//共通リソースコントローラ解放
	CmnRes_Free(ptr->CmnResCntPtr);

	//OAMレンダラー破棄
	REND_OAM_Delete();

	DeleteCharManager();
	DeletePlttManager();

	//AIコントローラー解放
	StealAI_End(ptr->AICntPtr);

	//サブ画面コントローラー解放
	StlSub_Free(ptr->SubDispCntPtr);

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);

	//イベントワーク解放
	PTFrame_FreeEventWork(work);

	// 上下画面を元に戻しておく
	sys.disp3DSW = DISP_3D_TO_MAIN;
	GF_Disp_DispSelect();

	//特殊効果オフ
	G2_BlendNone();
	//ヒープ解放
	sys_DeleteHeap( HEAPID_PT_STEAL );

	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * VRAM設定		ポケスロンでは、ポケモン表示だけで0x30000必要となる。
 * VRAM_AB(0x40000)でないとはいらん
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetVramBank(void)
{
	GF_BGL_DISPVRAM tbl = {
		GX_VRAM_BG_64_E,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット

		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット

		GX_VRAM_OBJ_256_AB,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット

		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット

		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &tbl );
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	BG初期化
 * @param	*ini		BGL
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void BgInit(GF_BGL_INI * ini)
{
	{	/* BG SYSTEM */
  	  GF_BGL_SYS_HEADER BGsys_data = {
    	  GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BGMODE_0, GX_BG0_AS_2D,
    	};
  	  GF_BGL_InitBG( &BGsys_data );
  	}

  	//メイン
  	{	/* MAIN DISP BG0 */
    	GF_BGL_BGCNT_HEADER MBg0_Data = {
	      0, 0, 0x2000, 0,
    	  GF_BGL_SCRSIZ_512x512, GX_BG_COLORMODE_16,
		  GX_BG_SCRBASE_0xd000, GX_BG_CHARBASE_0x00000,
		  GX_BG_EXTPLTT_01, 3, 0, 0, FALSE
   	 };
   	 GF_BGL_BGControlSet( ini, GF_BGL_FRAME0_M, &MBg0_Data, GF_BGL_MODE_TEXT );
   	 GF_BGL_ScrClear( ini, GF_BGL_FRAME0_M );
 	}
	{	/* MAIN DISP BG3 */								//レコード
    	GF_BGL_BGCNT_HEADER MBg3_Data = {
	      0, 0, 0x800, 0,
    	  GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
		  GX_BG_SCRBASE_0x8000, GX_BG_CHARBASE_0x04000,
		  GX_BG_EXTPLTT_01, 0, 0, 0, FALSE
   	 };
   	 GF_BGL_BGControlSet( ini, GF_BGL_FRAME3_M, &MBg3_Data, GF_BGL_MODE_TEXT );
   	 GF_BGL_ScrClear( ini, GF_BGL_FRAME3_M );
 	}

	  //サブ
	{	/* SUB DISP BG0 */
 	   GF_BGL_BGCNT_HEADER SBg0_Data = {
    	  	0, 0, 0x800, 0,
   	  		GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x0c000,
    		GX_BG_EXTPLTT_01, 0, 0, 0, FALSE
  	  };
 	  GF_BGL_BGControlSet( ini, GF_BGL_FRAME0_S, &SBg0_Data, GF_BGL_MODE_TEXT );
  	  GF_BGL_ScrClear( ini, GF_BGL_FRAME0_S );
 	}

 	{	/* SUB DISP BG1 */
	    GF_BGL_BGCNT_HEADER SBg1_Data = {
    	  	0, 0, 0x800, 0,
 	  		GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
 	   		GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000,
  	   		GX_BG_EXTPLTT_01, 2, 0, 0, FALSE
		};
    	GF_BGL_BGControlSet( ini, GF_BGL_FRAME1_S, &SBg1_Data, GF_BGL_MODE_TEXT );
    	GF_BGL_ScrClear( ini, GF_BGL_FRAME1_S );
	}

	{	/* SUB DISP BG2 */
		GF_BGL_BGCNT_HEADER SBg2_Data = {
			0, 0, 0x800, 0,
		    GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
      		GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x04000,
      		GX_BG_EXTPLTT_01, 3, 0, 0, FALSE
    	};
	    GF_BGL_BGControlSet( ini, GF_BGL_FRAME2_S, &SBg2_Data, GF_BGL_MODE_TEXT );
  	  	GF_BGL_ScrClear( ini, GF_BGL_FRAME2_S );
 	 }

	//レコードＢＧ非表示
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG3, VISIBLE_OFF );
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	グラフィックセット
 * @param	ptr			アプリポインタ
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetGraphic(PKTHLN_STL_PTR ptr)
{
	//メインキャラ

	ArcUtil_BgCharSet(ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_bg_main_ncgr,
						ptr->bgl, GF_BGL_FRAME0_M, 0, 0, FALSE, ptr->HeapID);

	//転送用キャラ
	ptr->BgCharData = ArcUtil_Load( ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_bg_main_trans_ncgr, FALSE, ptr->HeapID, ALLOC_TOP );
	NNS_G2dGetUnpackedBGCharacterData( ptr->BgCharData, &ptr->TransCharData );

	ArcUtil_ScrnSet(ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_bg_main_nscr,
						ptr->bgl, GF_BGL_FRAME0_M, 0, 0, FALSE, ptr->HeapID);

	//メインパレット
	ArcUtil_PalSet( ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_bg_main_nclr,
						PALTYPE_MAIN_BG, 0, 64, ptr->HeapID );
	//サブBG
	StlSub_SetBG(ptr->SubDispCntPtr);
}

//----------------------------------------------------------------------------
/**
 *	@brief		ＯＢＪセット
 *
 *	@param	pActCntPtr		アクターコントローラポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetObj(PKTHLN_CLACT_CNT_PTR pActCntPtr)
{
	PkthlnClAct_SetChar( pActCntPtr,
					ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_obj_main_NCGR,
					RES_CODE_STL_MAIN, NNS_G2D_VRAM_TYPE_2DMAIN);
	PkthlnClAct_SetPaltt( pActCntPtr,
					ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_obj_main_NCLR,
					RES_CODE_STL_MAIN, NNS_G2D_VRAM_TYPE_2DMAIN, STL_MAIN_OBJ_PALETTE_NUM	);
	PkthlnClAct_SetCell( pActCntPtr,
					ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_obj_main_NCER, RES_CODE_STL_MAIN	);
	PkthlnClAct_SetAnm(	pActCntPtr,
					ARC_PKTHEV_STEAL, NARC_pkthev_steal_steal_obj_main_NANR, RES_CODE_STL_MAIN	);
}

//----------------------------------------------------------------------------
/**
 *	@brief	アクターセットアップ
 *
 *  @param	ptr				競技ポインタ
 *	@param	pActCntPtr		アクターコントローラポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetAct( PKTHLN_STL_PTR ptr, PKTHLN_CLACT_CNT_PTR pActCntPtr)
{
	int i;
	//障害物
	for (i=0;i<OBST_NUM_MAX;i++){
		ptr->Obst[i].ActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_OBST);
		PkthlnClAct_ChgAnm(ptr->Obst[i].ActPtr, 1);
	}

	//パラソル
	for (i=0;i<PARASOL_NUM_MAX;i++){
		ptr->Parasol[i].PoleActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_POLE);
		PkthlnClAct_ChgAnm(ptr->Parasol[i].PoleActPtr, 6);
		ptr->Parasol[i].RoofActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_ROOF);
		PkthlnClAct_ChgAnm(ptr->Parasol[i].RoofActPtr, 5);
	}

	//ステート・ポイントゲット・旗取得
	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		u8 j;
		ptr->Poke[i].StateActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_STATE);
		PkthlnClAct_ChgAnm(ptr->Poke[i].StateActPtr, 2);
		for(j=0;j<PT_ACT_NUM;j++){
			ptr->Poke[i].PtActPtr[j] = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_PTGET);
			PkthlnClAct_ChgAnm(ptr->Poke[i].PtActPtr[j], 3);
			//ポイント取得プライオリティセット
			PkthlnClAct_SetPriority(ptr->Poke[i].PtActPtr[j], PRI_GET);
		}
		ptr->Poke[i].FlgGetActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_FLGGET);
		PkthlnClAct_ChgAnm(ptr->Poke[i].FlgGetActPtr, 8);
	}

	//ヒットエフェクト
	for(i=0;i<HIT_EFFECT_NUM;i++){
		ptr->HitActPtr[i] = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_HIT);
		PkthlnClAct_ChgAnm(ptr->HitActPtr[i], 7);
		//プライオリティセット
		PkthlnClAct_SetPriority(ptr->HitActPtr[i], PRI_STL_HIT);
	}
	//砂煙エフェクト
	for(i=0;i<SND_EFFECT_NUM;i++){
		ptr->SndActPtr[i] = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_SND);
		PkthlnClAct_ChgAnm(ptr->SndActPtr[i], 4);
	}

	//旗・煙
	for(i=0;i<FLAG_DISP_MAX;i++){
		ptr->FlagData.Flag[i].EffActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_FSMG);
		ptr->FlagData.Flag[i].ActPtr = PkthlnClAct_SetGetActor(pActCntPtr, 2, NNS_G2D_VRAM_TYPE_2DMAIN, RES_CODE_STL_MAIN, ACT_CODE_STL_FLAG);
		PkthlnClAct_ChgAnm(ptr->FlagData.Flag[i].ActPtr, 0);
		PkthlnClAct_ChgAnm(ptr->FlagData.Flag[i].EffActPtr, 4);
	}
}



//----------------------------------------------------------------------------
/**
 *	@brief	シーケンス関数
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@return	FALSE
 */
//-----------------------------------------------------------------------------
static BOOL STL_Func_Phase0(PKTHLN_PTR work, u8 *seq)
{
	OBJ_CHAR_POS obj_char_pos[50];
	OBJ_CHAR_POS *obst;
	OBJ_CHAR_POS *parasol;
	OBJ_CHAR_POS *flag;

	int i;
	COMM_EVENT_COMMON_DATA * data;
	STL_PARENT_DATA *parent;
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	switch(*seq){
	case 0:
		data = PTFrame_GetEvtComCmnData(work);
		parent = PKTHLN_CommPack_GetData(&data->ReciveShareData);

		//アーカイブ取得
		ArchiveDataLoad(obj_char_pos, ARC_PKTHEV_STL_DAT, ptr->ChildMapIdx);
		parasol = &obj_char_pos[0];
		obst = &obj_char_pos[10];
		flag = &obj_char_pos[30];

		//障害物データをローカルで作成
		for(i=0;i<OBST_NUM_MAX;i++){
			u16 y;
			u16 x;
			y = obst[i].Y * 8;
			x = obst[i].X * 8;

			ptr->ObstPos[i].x = obst[i].X * 8;
			ptr->ObstPos[i].y = obst[i].Y * 8;

			if ( (x!=0)&&(y!=0) ){
				VecFx32 vec;
				ptr->Obst[i].Valid = TRUE;
				ptr->Obst[i].X = x;
				ptr->Obst[i].Y = y;
				//可視状態
				PkthlnClAct_SetActive(ptr->Obst[i].ActPtr, 1, 1);
			}
		}
		//パラソルデータをローカルで作成
		for(i=0;i<PARASOL_NUM_MAX;i++){
			u16 y;
			u16 x;
			y = parasol[i].Y * 8;
			x = parasol[i].X * 8;
			ptr->ParasolPos[i].x = parasol[i].X * 8;
			ptr->ParasolPos[i].y = parasol[i].Y * 8;

			if ( (x!=0)&&(y!=0) ){
				VecFx32 vec;
				ptr->Parasol[i].Valid = TRUE;
				ptr->Parasol[i].X = x;
				ptr->Parasol[i].Y = y;
				//可視状態
				PkthlnClAct_SetActive(ptr->Parasol[i].PoleActPtr, 1, 1);
				PkthlnClAct_SetActive(ptr->Parasol[i].RoofActPtr, 1, 1);
			}
		}

		//旗データをローカルで作成
		for(i=0;i<FLAG_CONT_MAX;i++){
			ptr->FlagData.FlgPos[i].x = flag[i].X * 8;	//test_flag_pos[i];
			ptr->FlagData.FlgPos[i].y = flag[i].Y * 8;
		}

		//AI用にデータをセットアップ
		if ( PTFrameGetCurrentID(work) == COMM_PARENT_ID ){
			//旗ジェネレート
			GenerateFlag(ptr);
			//障害物データをセットアップ
			StealAI_SetUpObstInfo(ptr->AICntPtr, &obj_char_pos[10]);
			//パラソルデータをセットアップ
			StealAI_SetUpObstInfo(ptr->AICntPtr, &obj_char_pos[0]);
			//フラッグデータをセットアップ
			StealAI_SetupFlagPtr(ptr->AICntPtr, ptr->FlagData.Flag);
		}
		//不動ＯＢＪのプライオリティセット
		SetObjPriority(ptr);
		//初期化終了
		sys_PrintHeapFreeSize( ptr->HeapID );
		GF_ASSERT(sys_CheckHeapSafe( HEAPID_POKETHLON));
		(*seq)++;
		//通信同期待ちセット
		PTFrame_SetSynchroID(work, PKTLN_SYNC_ID_STL_START_WAIT);
		break;
	case 1:
		//みんな一緒にフェードインリクエスト
		WIPE_SYS_Start(	WIPE_PATTERN_FSAM, WIPE_TYPE_SHUTTERIN_DOWN,
						WIPE_TYPE_SHUTTERIN_DOWN, WIPE_FADE_BLACK,
						WIPE_DEF_DIV, WIPE_DEF_SYNC, ptr->HeapID );
		(*seq)++;
		break;
	case 2:
		//フェードイン待ち
		if( WIPE_SYS_EndCheck() ){
			//シーケンスシフト
			PTFrame_SetNextFuncTblIdx(work, STL_SEQ_PHASE1);
		}
		break;
	}

	SetDraw(work);

	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	シーケンス関数
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@return	FALSE
 */
//-----------------------------------------------------------------------------
static BOOL STL_Func_Phase1(PKTHLN_PTR work, u8 *seq)
{
	BOOL rc;
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	switch(*seq){
	case 0:	//カウント
		SetDraw(work);
		if ( PTFrame_CountDown(work) ){
			(*seq)++;
		}
		break;
	case 1:
		CommMain(work);
		if ( ControlMain(work) ){
			(*seq)++;
		}
		break;
	case 2:
		CommMain(work);
		if ( PTFrame_DispEnd(work) ){
			//フェードアウトリクエスト
			WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT,
							WIPE_TYPE_FADEOUT, WIPE_FADE_BLACK,
							WIPE_DEF_DIV, WIPE_DEF_SYNC, ptr->HeapID );
			//シーケンスシフト
			PTFrame_SetNextFuncTblIdx(work, STL_SEQ_PHASE2);
		}
		break;
	}


	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	シーケンス関数
 *
 *	@param	work		ポケスロンポインタ
 *	@param	*seq		シーケンサ
 *
 *	@return	TRUE
 */
//-----------------------------------------------------------------------------
static BOOL STL_Func_Phase2(PKTHLN_PTR work, u8 *seq)
{
	int i,j;
	PKTHLN_STL_PTR ptr;
	STL_PARENT_DATA *parent;
	COMM_EVENT_COMMON_DATA *data;
	data = PTFrame_GetEvtComCmnData(work);
	ptr = PTFrame_GetEventWorkPtr(work);

	if (*seq == 0){
		//フェードアウト待ち
		if ( WIPE_SYS_EndCheck() ){
			*seq = 1;
		}
		return FALSE;
	}

	//結果はすべて親が管理しているので、子は処理をスルー
	if (PTFrameGetCurrentID(work) != COMM_PARENT_ID){
		return TRUE;
	}
	parent = PKTHLN_CommPack_GetData(&data->SendShareData);

	//結果セット
	for (i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		u16 point,temp_point,total;
		point = (parent->St1[i] >> 18) & 0x3ff;		//10ビットマスク
		temp_point = (parent->St4[i] >> 11) & 0x1f;		//5ビットマスク
		total = point+temp_point;
		if (total > POINT_MAX){
			total = POINT_MAX;
		}
		PTFrame_SetEvtResultOrg(work, i, total);
	}
	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	通信データ関連メイン処理
 * @param	work		ポケスロンポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void CommMain(PKTHLN_PTR work)
{
	int i,j;
	PKTHLN_STL_PTR ptr;
	COMM_EVENT_COMMON_DATA *data;
	data = PTFrame_GetEvtComCmnData(work);
	ptr = PTFrame_GetEventWorkPtr(work);

	//親動作
	if (PTFrameGetCurrentID(work) == COMM_PARENT_ID){
		//終了フラグが立っているならば、通信データのセットのみを行い処理を打ち切る
		if (ptr->EndFlg){
			//情報セット
			SetCommInfo(ptr,  PKTHLN_CommPack_GetData(&data->SendShareData));
			return;
		}

		//親データは直接レシーバにセット
		{
			STL_CHILD_DATA *child;
			STL_CHILD_DATA *child_rec;

			child_rec = PKTHLN_CommPack_GetData(&data->ReciveData[0]);
			child = PKTHLN_CommPack_GetData(&data->SendData);
			(*child_rec) = (*child);
		}

		//時間経過
#ifdef PM_DEBUG					//こっちデバッグ用
		if (!DebugPkthlnWk.TimeInfinity){
			if (ptr->CommTime > 0){
				ptr->CommTime--;
			}
		}
#else							//こっち製品用
		if (ptr->CommTime > 0){
			ptr->CommTime--;
		}
#endif

		//AI実行
#ifdef PM_DEBUG										//こっちデバッグ用
		if ( !DebugPkthlnWk.AI_Stop ){
			StealAI_Execute(ptr->AICntPtr);
		}
#else												//こっち製品用
		StealAI_Execute(ptr->AICntPtr);
#endif

		//砂煙エフェクトフラグオフ
		ptr->SndEff = 0;

		//プレーヤー数ループ
		for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
			STL_CHILD_DATA *child_data;
			child_data = PKTHLN_CommPack_GetData(&data->ReciveData[i]);

			//タッチ状況を整理
			if (child_data->TouchValid){
				if ( (ptr->TpState[i].Trg)&&(ptr->TpState[i].Cont) ){
					ptr->TpState[i].Trg = FALSE;
				}else if((!ptr->TpState[i].Trg)&&(!ptr->TpState[i].Cont)){
					ptr->TpState[i].Trg = TRUE;
					ptr->TpState[i].Cont = TRUE;
				}
			}else{
				ptr->TpState[i].Trg = FALSE;
				ptr->TpState[i].Cont = FALSE;
			}

			if (ptr->Poke[i].ChgFlg){	//交代中
				//子機からの反応を取得
				if ( (ptr->Poke[i].ChgState == CHG_MOVE_DOWN)&&(child_data->ChgState == CHILD_CHG_DOWN_END) ){
					OS_Printf("%dのポケ退避が終了\n");
					//ポケ交代
					ptr->Poke[i].StlPokeIdx = (ptr->Poke[i].StlPokeIdx+1)%ENTRY_MAX;
					//ポケ入場アニメに移行する
					ptr->Poke[i].ChgState = CHG_MOVE_UP;
					OS_Printf("%dの次のポケはインデックス%d\n",i, ptr->Poke[i].StlPokeIdx);
					//方向上
					ptr->Poke[i].Dir = POKE_DIR_UP;
				}else if( (ptr->Poke[i].ChgState == CHG_MOVE_UP)&&(child_data->ChgState == CHILD_CHG_UP_END) ){
					OS_Printf("%dのポケの入場が終了\n");
					//ポケ交代終了
					ptr->Poke[i].ChgState = CHG_MOVE_NONE;
					ptr->Poke[i].ChgFlg = 0;
					ptr->Poke[i].Pause = 0;
					//方向上
					ptr->Poke[i].Dir = POKE_DIR_UP;
				}
				//交代中はタッチしていないとみなす
				ptr->HoldPoke[i] = FALSE;
				ptr->Poke[i].TouchTime = 0;
				ptr->Poke[i].TPos.x = 0;
				ptr->Poke[i].TPos.y = 0;
				ptr->Poke[i].TPos.z = 0;
				ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
			}else if (ptr->Poke[i].State == POKE_ST_PANIC){	//気絶中
				//気絶中はタッチしていないとみなす
				ptr->HoldPoke[i] = FALSE;
				ptr->Poke[i].TouchTime = 0;
				ptr->Poke[i].TPos.x = 0;
				ptr->Poke[i].TPos.y = 0;
				ptr->Poke[i].TPos.z = 0;
				ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
			}else if (ptr->Poke[i].HitFrame){			//ヒットポーズ中
				//ヒットポーズ中はタッチしていないとみなす
				ptr->HoldPoke[i] = FALSE;
				ptr->Poke[i].TouchTime = 0;
				ptr->Poke[i].TPos.x = 0;
				ptr->Poke[i].TPos.y = 0;
				ptr->Poke[i].TPos.z = 0;
				ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
			}else if (ptr->Poke[i].Pause){			//ポーズ中
				//ポーズ中はタッチしていないとみなす
				ptr->HoldPoke[i] = FALSE;
				ptr->Poke[i].TouchTime = 0;
				ptr->Poke[i].TPos.x = 0;
				ptr->Poke[i].TPos.y = 0;
				ptr->Poke[i].TPos.z = 0;
				ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
			}else{
				BOOL clear_flg = FALSE;
				if (ptr->TpState[i].Trg){
					BOOL rc;
					//自分のポケモンをタッチしたかを検出
					rc = CheckPokeTouch(ptr, i, child_data->TpX, child_data->TpY);
					//自分のポケか？
					if ( rc ){
						//ホールド登録
						ptr->HoldPoke[i] = TRUE;
						//タッチ座標記憶
						ptr->Poke[i].TPos.x = child_data->TpX * FX32_ONE;
						ptr->Poke[i].TPos.y = child_data->TpY * FX32_ONE;
						ptr->Poke[i].TPos.z = 0;
						ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
					}
				}else if (ptr->TpState[i].Cont){	//ベタ押し
					//タッチ時間加算
					if (ptr->Poke[i].TouchTime < TOUCH_TIME_MAX){
						ptr->Poke[i].TouchTime++;
					}else{
						//ブレーキ状態
						ptr->Brake = 1;
					}
					//ホールドポケいなければ、処理しない
					if (ptr->HoldPoke[i] == FALSE){
						continue;
					}
					//ベタタッチ座標更新
					ptr->Poke[i].LastTPos.x = child_data->TpX * FX32_ONE;
					ptr->Poke[i].LastTPos.y = child_data->TpY * FX32_ONE;
				}else{	//タッチしていない
					if ( ptr->HoldPoke[i] != FALSE ){
						//加速度算出時間内ならば、リリースポイントから加速度を求める
						if (ptr->Poke[i].TouchTime <= TOUCH_TIME_ACCEL){
							//移動ベクトル決定処理を行う
							ptr->Poke[i].MoveVecDcd = TRUE;
						}
						//ホールド解除
						ptr->HoldPoke[i] = FALSE;
						//ブレーキ状態解除
						ptr->Brake = 0;
					}
					clear_flg = TRUE;
				}
				//移動ベクトル決定処理
				if (ptr->Poke[i].MoveVecDcd){
					u8 idx;
					VecFx32 poke_speed;
					VecFx32 vec;
					VecFx32 add = {0,0,0};

					VecFx32 old;
					VecFx32 new;
					float len, sp_len;
					fx32 scalar;
					float accel,speed;
					float max_speed;

					idx = ptr->Poke[i].StlPokeIdx;

					accel = ptr->Poke[i].Param[idx].Accel1;			//テクニック依存
					speed = ptr->Poke[i].Param[idx].Accel2;			//スピード依存
					max_speed = GetMaxSpeed( &ptr->Poke[i], idx );
					scalar = (accel*speed/ACCEL_DIV)*FX32_ONE;

					VEC_Subtract( &ptr->Poke[i].LastTPos, &ptr->Poke[i].TPos, &vec );

//					OS_Printf("VEC_XY=%d,%d\n",vec.x , vec.y);

					VEC_MultAdd( scalar, &vec, &add, &vec );
///					OS_Printf("accel_len_bf=%d\n",VEC_Mag(&vec));
					len = VEC_Mag(&vec) / FX32_ONE;
					//求めた長さに加速係数・スピード係数を乗算し、補正係数で除算する
///					OS_Printf("accel_len_af=%f\n",len);

					poke_speed = ptr->Poke[i].Speed;
					old = ptr->Poke[i].Speed;

					//仮加算(ここでの仮は一時的というもので、デバッグの意味合いは含んでいません)
					AddSpeedVec(&poke_speed, &vec, &poke_speed);
					//限界スピードを超えたかをチェック
					sp_len = VEC_Mag(&poke_speed);
					if ( sp_len > max_speed*FX32_ONE ){		//超えた
						VecFx32 add = {0,0,0};
						//正規化後max_speed倍
						VEC_Normalize(&poke_speed, &poke_speed);
						VEC_MultAdd(max_speed*FX32_ONE, &poke_speed, &add, &ptr->Poke[i].Speed);
						VEC_MultAdd(max_speed*FX32_ONE, &poke_speed, &add, &new);
///						OS_Printf("補正\n");
					}else{		//超えてない
						//求めた加速度をスピードに加算
						AddSpeedVec(&ptr->Poke[i].Speed, &vec, &ptr->Poke[i].Speed);
						new = vec;
///						OS_Printf("そのまま\n");
					}

					//方向ベクトルから、ポケモンの向きを決定する
					ptr->Poke[i].Dir = CalcDir(&ptr->Poke[i].Speed);
#if 0		//仕様変更	移動時は常に砂エフェクトが出る
					//切り替えしエフェクト判定
					{
						fx32 dot;
						fx32 old_len;
						old_len = VEC_Mag(&old);
						dot = VEC_DotProduct(&old, &new);
						if ( (old_len != 0)&&(dot <= 0) ){

							//反対方向に移動を開始
							if ( SND_EFF_LEN <= VEC_Mag(&new) ){
								//エフェクトリクエスト
								ptr->SndEff = 1;
								ptr->SndEffX = ptr->Poke[i].Pos.x / FX32_ONE;
								ptr->SndEffY = ptr->Poke[i].Pos.y / FX32_ONE;
							}
						}
					}
#else
					ptr->SndEff = 1;
					ptr->SndEffX = ptr->Poke[i].Pos.x / FX32_ONE;
					ptr->SndEffY = ptr->Poke[i].Pos.y / FX32_ONE;
#endif
					ptr->Poke[i].MoveVecDcd = FALSE;

				}

				if (clear_flg){
					ptr->Poke[i].TouchTime = 0;
					ptr->Poke[i].TPos.x = 0;
					ptr->Poke[i].TPos.y = 0;
					ptr->Poke[i].TPos.z = 0;
					ptr->Poke[i].LastTPos = ptr->Poke[i].TPos;
				}
			}//end if (ptr->Poke[i].ChgFlg)
		}	//end for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++)

		//ポケモンの移動
		MovePoke(work);
		//旗のジェネレート
		GenerateFlag(ptr);

		//終了判定
///		OS_Printf("ＧａｍｅＴｉｍｅ= %d\n",ptr->CommTime);
		if (ptr->CommTime <= 0){
			ptr->EndFlg = 1;		//終了フラグ
		}else{
			ptr->EndFlg = 0;
		}

		//情報セット
		SetCommInfo(ptr,  PKTHLN_CommPack_GetData(&data->SendShareData));
	}
}

//--------------------------------------------------------------------------------------------
/**
 * @brief	通信データセット
 * @param	ptr		ポケスロンアプリポインタ
 * @param	parent	親データ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetCommInfo(PKTHLN_STL_PTR ptr, STL_PARENT_DATA *parent)
{
	int i,j;
	u8 chg_state;
	u8 pause;
	int st3;
	int fat_state;
	u8 se_bit;

	chg_state = 0;
	pause = 0;
	st3 = 0;
	fat_state = 0;
	se_bit = 0;

	for(i=0;i<FLAG_DISP_MAX;i++){
		parent->St4[i] = ptr->FlagData.Flag[i].Idx;
	}
	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		int x,y;
		int dir;
		int st1;

		STL_POKE *stl_poke;
		stl_poke = &ptr->Poke[i];

		x = stl_poke->Pos.x / FX32_ONE;
		y = stl_poke->Pos.y / FX32_ONE;
		st1 = x | (y<<9) | (stl_poke->Point<<18) | (stl_poke->FlagNum <<28);
		parent->St1[i] = st1;
		parent->St4[i] |= (stl_poke->StlPokeIdx<<5);
		parent->St4[i] |= ((stl_poke->Dir-1)<<7);
		parent->St4[i] |= (stl_poke->State << 9);
		parent->St4[i] |= (stl_poke->TempPoint << 11);
		pause |= (stl_poke->Pause << i);
		chg_state |= (stl_poke->ChgState << (i*2));
		se_bit |= (ptr->SeFlg[i] << i);
	}
	parent->St3 = 0;
	parent->St3 |= (ptr->HitEffX);
	parent->St3 |= (ptr->HitEffY << 9);
	parent->St3 |= (ptr->HitEff << 18);
	parent->St3 |= (se_bit << 19);
	parent->St2 = 0;
	parent->St2 |= (ptr->SndEffX);
	parent->St2 |= (ptr->SndEffY << 9);
	parent->St2 |= (ptr->SndEff << 18);
	parent->St2 |= (pause << 19);
	parent->St2 |= (chg_state << 23);
	parent->St2 |= (ptr->EndFlg << 31);

	parent->Time = ptr->CommTime;

}

//----------------------------------------------------------------------------
/**
 *	@brief		メイン関数
 *
 *	@param	work	ポケスロンポインタ
 *
 *	@return	終了でTRUE
 */
//-----------------------------------------------------------------------------
static BOOL ControlMain(PKTHLN_PTR work)
{
	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	STL_CHILD_DATA *child_data;
	COMM_EVENT_COMMON_DATA *data;
	data = PTFrame_GetEvtComCmnData(work);
	child_data = PKTHLN_CommPack_GetData(&data->SendData);
	child_data->TouchValid = FALSE;

	//終了検出
	{
		u8 end;
		STL_PARENT_DATA *parent;
		parent = PKTHLN_CommPack_GetData(&data->ReciveShareData);
		end = (parent->St2 >> 31) & 0x1;	//1ビットマスク
#ifdef PM_DEBUG
		if (sys.trg & PAD_BUTTON_X){
			end = 1;
		}
#endif
		if (end){
			//アクター停止
			PkthlnClAct_AllAnmStop(ptr->ActCntPtr, 1);
			PokeAct_AllAnmStop(ptr->PokeActCntPtr, 1);
/**
			//フレームワークにニューレコードチェック用のレコード値をセット
			PTFrame_SetCheckRecord(work, total);
			SetRecordStr(ptr, total);
*/
			//レコードコールバック関数をセット
			PTFrame_SetRecordCallBack(work, RecCallBack);
			return TRUE;
		}
	}

	//タッチ座標検出
	if (GF_TP_GetTrg()){
		//アクションポイント加算「タッチ回数」
		PTFrame_AddActionPoint(	work, PTFrameGetCurrentID(work), ENTRY_MAX, ADD_TYPE_TOUCH, 1 );
	}
	if (GF_TP_GetCont()){
		//通信データに座標をセット
		child_data->TpX = sys.tp_x;
		child_data->TpY = sys.tp_y;
		child_data->TouchValid = TRUE;
	}

	SetDraw(work);

	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief		描画座標関連セット関数
 *
 *	@param	work	ポケスロンポインタ
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetDraw(PKTHLN_PTR work)
{
	u8 my_net_id;
	COMM_EVENT_COMMON_DATA * data;
	STL_PARENT_DATA *parent;

	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	data = PTFrame_GetEvtComCmnData(work);
	parent = PKTHLN_CommPack_GetData(&data->ReciveShareData);
	my_net_id = PTFrameGetCurrentID(work);

	//自分の座標からＢＧのスクロール値を計算
	{
		int x_ofs,y_ofs;
		int poke_x, poke_y;
		poke_x = parent->St1[my_net_id] & 0x1ff;	//9ビットマスク
		poke_y = (parent->St1[my_net_id] >> 9) & 0x1ff;	//9ビットマスク
		x_ofs = poke_x - START_POKE_POS_X;
		y_ofs = poke_y - START_POKE_POS_Y;


		GF_BGL_ScrollReq( ptr->bgl, GF_BGL_FRAME0_M, GF_BGL_SCROLL_X_SET, x_ofs );
		GF_BGL_ScrollReq( ptr->bgl, GF_BGL_FRAME0_M, GF_BGL_SCROLL_Y_SET, y_ofs );

		CalcPokeDispPos(work, my_net_id, ptr->Poke, data);
		//障害物表示
		CalcObstDispPos(ptr, poke_x, poke_y);
		//パラソル表示
		CalcParasolDispPos(ptr, poke_x, poke_y);
		//旗表示
		CalcFlagDispPos(ptr, parent, poke_x, poke_y);
	}

	//転送アニメ
	TransAnmMain(ptr);

	//タイマー
	StlSub_DispTime(ptr->SubDispCntPtr, parent->Time);

	//ラスト３秒
	PTFrame_DispLastCount(work, parent->Time);

}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモンをタッチしているかを判定する
 *
 *	@param	ptr		競技ポインタ
 *	@param	inNetID	ネットID
 *	@param	inX		X座標
 *	@param	inY		Y座標
 *
 *	@return u8 タッチしたポケモンインデックス
 */
//-----------------------------------------------------------------------------
static BOOL CheckPokeTouch(PKTHLN_STL_PTR ptr, const u8 inNetID, const u16 inX, const u16 inY)
{
	u8 i;

	STL_POKE *stl_poke;
	POKE_ACT_PTR poke_ptr;
	int tx,ty;

	stl_poke = &ptr->Poke[inNetID];

	if (0/*stl_poke->State == POKE_NONE*/){
		return FALSE;
	}

	GF_ASSERT(stl_poke->StlPokeIdx < ENTRY_MAX);

	poke_ptr = stl_poke->PokeActPtr[stl_poke->StlPokeIdx];

	//タッチ中心座標取得
	PokeAct_GetTouchPosByShadowPos(poke_ptr, START_POKE_POS_X, START_POKE_POS_Y, &tx, &ty);

	if ( PokeAct_CheckTouch(poke_ptr, tx*FX32_ONE, ty*FX32_ONE, inX, inY) ){
		//タッチしている
		OS_Printf("%d:ポケにタッチ\n",inNetID);
		return TRUE;
	}
	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	交代ボタンをタッチしているかを判定する
 *
 *	@param	ptr		競技ポインタ
 *	@param	inX		X座標
 *	@param	inY		Y座標
 *
 *	@return u8 タッチしたポケモンインデックス
 */
//-----------------------------------------------------------------------------
static BOOL CheckChgBtnTouch(PKTHLN_STL_PTR ptr, const u16 inX, const u16 inY)
{
	if ( (0<=inX)&&(inX<CHG_BTN_W) &&
		 (0<=inY)&&(inY<CHG_BTN_H)	){
		return TRUE;
	}
	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモンの移動
 *
 *	@param	work	ポケスロンポインタ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MovePoke(PKTHLN_PTR work)
{
	HIT_RC hit_rc;
	u16 rc;
	int i,j;
	BOOL hit_eff;
	VecFx32 hit_vec;
	u8 hit_frame_flg[ENTRY_MEMBER_NUM_MAX];

	PKTHLN_STL_PTR ptr = PTFrame_GetEventWorkPtr(work);

	ptr->HitEff = 0;

	//ヒットポーズ中の処理
	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		hit_frame_flg[i] = 0;
		if (ptr->Poke[i].HitFrame){
			MovePokeHitFrame(work, ptr, &ptr->Poke[i]);
			hit_frame_flg[i] = 1;
			continue;
		}
	}

	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		VecFx32 old_pos;
		STL_POKE *stl_poke;
		stl_poke = &ptr->Poke[i];

		//ヒット中は移動関連処理をスルー
		if (hit_frame_flg[i]){
			continue;
		}

		//ゴールエリア判定
		if ( CheckGoal(stl_poke) ){
			//ゴールしたので旗を得点に換算
			stl_poke->TempPoint = CalcPointByGetFlag(stl_poke->FlagNum);
			//旗数を0にする
			stl_poke->FlagNum = 0;
			//ポーズ状態
			stl_poke->Pause = 1;
			//スピードとか向きとかをクリア
			stl_poke->Speed.x = 0;
			stl_poke->Speed.y = 0;
			stl_poke->Speed.z = 0;
			stl_poke->Dir = POKE_DIR_DOWN;
			//得点加算時間セット
			stl_poke->PtGetTime = PT_GET_HOLD_TIME;
			//アクションポイント加算「得点回数」
			PTFrame_AddActionPoint(	work, stl_poke->NetID, stl_poke->StlPokeIdx, ADD_TYPE_GET, stl_poke->TempPoint );
		}

		//得点取得
		if ( (stl_poke->PtGetTime)&&(stl_poke->Pause) ){	//得点加算時間が0で無い場合、得点加算中
			if (!stl_poke->PtUpTime){
				if (stl_poke->TempPoint){	//テンポラリ得点がある場合
					//ポイント加算
					stl_poke->Point++;
					if (stl_poke->Point > POINT_MAX){
						stl_poke->Point = POINT_MAX;
					}
					//テンポラリ点数減算
					stl_poke->TempPoint--;
				}
				//ポイント取得ホールド時間減算
				stl_poke->PtGetTime--;
				if ( stl_poke->PtGetTime <= 0 ){
					stl_poke->PtGetTime = 0;
					//交代中フラグＯＮ
					stl_poke->ChgFlg = 1;
					//デモシーケンス変更
					stl_poke->ChgState = CHG_MOVE_DOWN;
					//アクションポイント加算「交代」
					PTFrame_AddActionPoint(	work, stl_poke->NetID, stl_poke->StlPokeIdx, ADD_TYPE_CHANGE, 1 );
				}else{
					//次のポイント取得までのマージンセット
					stl_poke->PtUpTime = PT_GET_MARGINE;
				}
			}else{
				stl_poke->PtUpTime--;
			}
		}

		//ポーズ中は移動関連処理をスルー
		if (stl_poke->Pause){
			continue;
		}

		//今の座標を保存
		old_pos = stl_poke->Pos;
		//座標更新
		VEC_Add(&stl_poke->Pos, &stl_poke->Speed, &stl_poke->Pos);

		//リミット計算
		if ( (stl_poke->Pos.x < GOAL_X_LIMIT_MIN * FX32_ONE)||
				(GOAL_X_LIMIT_MAX * FX32_ONE < stl_poke->Pos.x) ){
			if (stl_poke->Pos.y < WALL_Y_LIMIT_MIN * FX32_ONE){
				stl_poke->Pos.y = WALL_Y_LIMIT_MIN * FX32_ONE;
			}else if(WALL_Y_LIMIT_MAX * FX32_ONE < stl_poke->Pos.y){
				stl_poke->Pos.y = WALL_Y_LIMIT_MAX * FX32_ONE;
			}
		}else{
			if (stl_poke->Pos.y < WALL_Y_LIMIT_MIN * FX32_ONE){
				stl_poke->Pos.y = WALL_Y_LIMIT_MIN * FX32_ONE;
			}else if(GOAL_Y_LIMIT_MAX * FX32_ONE < stl_poke->Pos.y){
				stl_poke->Pos.y = GOAL_Y_LIMIT_MAX * FX32_ONE;
			}
		}
		if ( stl_poke->Pos.y > WALL_Y_LIMIT_MAX * FX32_ONE ){
			if (stl_poke->Pos.x < GOAL_X_LIMIT_MIN * FX32_ONE){
				stl_poke->Pos.x = GOAL_X_LIMIT_MIN * FX32_ONE;
			}else if(GOAL_X_LIMIT_MAX * FX32_ONE < stl_poke->Pos.x){
				stl_poke->Pos.x = GOAL_X_LIMIT_MAX * FX32_ONE;
			}
		}else{
			if (stl_poke->Pos.x < WALL_X_LIMIT_MIN * FX32_ONE){
				stl_poke->Pos.x = WALL_X_LIMIT_MIN * FX32_ONE;
			}else if(WALL_X_LIMIT_MAX * FX32_ONE < stl_poke->Pos.x){
				stl_poke->Pos.x = WALL_X_LIMIT_MAX * FX32_ONE;
			}
		}

		//障害物とのヒット
		rc = HitCheckObst(ptr, stl_poke->HitRc,
				PokeAct_GetHitRange(stl_poke->PokeActPtr[stl_poke->StlPokeIdx]),
				&old_pos, &stl_poke->Pos, &stl_poke->Pos);
		hit_rc = rc & 0xff;		//8ビットマスク

		stl_poke->HitRc = hit_rc;

		switch(hit_rc){
		case HIT_RC_UWALL:
			if (stl_poke->Speed.y > 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		case HIT_RC_RWALL:
			if (stl_poke->Speed.x < 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			break;
		case HIT_RC_DWALL:
			if (stl_poke->Speed.y < 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		case HIT_RC_LWALL:
			if (stl_poke->Speed.x > 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			break;
		case HIT_RC_LU_VRT:
			if (stl_poke->Speed.x > 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			if (stl_poke->Speed.y > 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		case HIT_RC_RU_VRT:
			if (stl_poke->Speed.x < 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			if (stl_poke->Speed.y > 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		case HIT_RC_RD_VRT:
			if (stl_poke->Speed.x < 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			if (stl_poke->Speed.y < 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		case HIT_RC_LD_VRT:
			if (stl_poke->Speed.x > 0){
				stl_poke->Speed.x *= DEC_SP;
			}
			if (stl_poke->Speed.y < 0){
				stl_poke->Speed.y *= DEC_SP;
			}
			break;
		}

		//ポケモンとのヒット
		hit_eff = HitCheckPoke(work, ptr->Poke, &hit_vec);

		if ((!ptr->HitEff)&&hit_eff){
			ptr->HitEff = 1;
			ptr->HitEffX = hit_vec.x / FX32_ONE;
			ptr->HitEffY = hit_vec.y / FX32_ONE;
		}

		//減速処理
		{
			fx32 scalar;
			float weight;
			VecFx32 vec;
			fx32 len, sp_len;

			vec = stl_poke->Speed;
			len = VEC_Mag(&vec);
			if (len > 0){
///				OS_Printf("SP_VEC_XY=%d,%d\n",stl_poke->Speed.x , stl_poke->Speed.y);
				weight = 6.0;			//固定
				scalar = (weight * DECEL_COEF) * FX32_ONE;
				//ブレーキ分
				if (ptr->Brake){
					scalar += (3*FX32_ONE);
				}
				VEC_Normalize(&vec, &vec);
				vec.x = FX_Mul(vec.x, scalar);
				vec.y = FX_Mul(vec.y, scalar);
				len = VEC_Mag(&vec);
				sp_len = VEC_Mag(&stl_poke->Speed);
				if (sp_len>=len){
					VEC_Subtract( &stl_poke->Speed, &vec, &stl_poke->Speed);
				}else{
					stl_poke->Speed.x = 0;
					stl_poke->Speed.y = 0;
					OS_Printf("速度が0に戻った\n");
				}
#ifdef PM_DEBUG
				if (i==0){
					if (sp_len!=0){
						fx32 d_len;
						d_len = VEC_Mag(&stl_poke->Speed) / FX32_ONE;
						OS_Printf("d_len=%f\n",d_len);
					}
				}
#endif
			}
		}

		if (!stl_poke->ChgFlg){		//交代中ではない？
			if (stl_poke->State == POKE_ST_PANIC){	//気絶
				//気絶カウンタ
				OS_Printf("気絶回復中\n");
				stl_poke->PanicCount--;
				if (stl_poke->PanicCount == 0){
					stl_poke->State = POKE_ST_NORMAL;
				}
			}
		}
#ifdef PM_DEBUG
		if (sys.trg & PAD_BUTTON_R){
			if (i == 0){
				OS_Printf("pos = %d,%d\n",stl_poke->Pos.x/FX32_ONE, stl_poke->Pos.y/FX32_ONE);
			}
		}
#endif

		//旗取得
		GetFlag(&ptr->FlagData, stl_poke, &ptr->SeFlg[i]);
	}	//end for
}

//----------------------------------------------------------------------------
/**
 *	@brief	交代ボタンをタッチしているかを判定する
 *
 *	@param	work		ポケスロンポインタ
 *	@param	ptr			競技ポインタ
 *	@param	stl_poke	競技ポケモン
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MovePokeHitFrame(PKTHLN_PTR work, PKTHLN_STL_PTR ptr, STL_POKE *stl_poke)
{
#if 0
	BOOL hit_eff;
	VecFx32 hit_vec;

	//ポケモンとのヒット
	hit_eff = HitCheckPoke(work, ptr->Poke, &hit_vec);

	if ((!ptr->HitEff)&&hit_eff){
		ptr->HitEff = 1;
		ptr->HitEffX = hit_vec.x / FX32_ONE;
		ptr->HitEffY = hit_vec.y / FX32_ONE;
	}
#endif
	//ヒットポーズカウンタデクリメント
	if (stl_poke->HitFrame>0){
		stl_poke->HitFrame--;
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	自分のポケの表示位置から相対的に考えて、相手のポケの位置を算出
 *
 *  @param	work		ポケスロンワーク
 *  @param	inMyNetID	自分のネットID
 *	@param	inPokeList	競技ポケモンリスト
 *	@param	commData	通信データ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void CalcPokeDispPos(PKTHLN_PTR work,
							const u8 inMyNetID,
							STL_POKE *inPokeList,
							COMM_EVENT_COMMON_DATA *commData)
{
	int i,j;
	int len_x,len_y;
	int disp_x, disp_y;
	int x,y;
	u8 my_net_id;
	PKTHLN_STL_PTR ptr;
	BOOL is_parent;

	STL_PARENT_DATA *parent;
	STL_CHILD_DATA *child_data;

	my_net_id = PTFrameGetCurrentID(work);

	parent = PKTHLN_CommPack_GetData(&commData->ReciveShareData);

	ptr = PTFrame_GetEventWorkPtr(work);

	x = parent->St1[inMyNetID] & 0x1ff;	//9ビットマスク
	y = (parent->St1[inMyNetID]>>9) & 0x1ff;	//9ビットマスク

	//ヒットエフェクト表示
	{
		u8 hit_eff;
		hit_eff = (parent->St3 >> 18) & 0x1;		//1ビットマスク
		if (hit_eff){
			int eff_x,eff_y;
			eff_x = (parent->St3) & 0x1ff;		//9ビットマスク
			eff_y = (parent->St3>>9) & 0x1ff;		//9ビットマスク

			//座標保存
			ptr->HitX[ptr->HitEffIdx] = eff_x;
			ptr->HitY[ptr->HitEffIdx] = eff_y;

			//アニメ
			PkthlnClAct_SetActive(ptr->HitActPtr[ptr->HitEffIdx], 1, 1);
			PkthlnClAct_ChgAnm(ptr->HitActPtr[ptr->HitEffIdx], 7);
			//インデックス変更
			ptr->HitEffIdx = (ptr->HitEffIdx+1)%HIT_EFFECT_NUM;

			{
				int hx,hy;
				hx = START_POKE_POS_X + eff_x - x;
				hy = START_POKE_POS_Y + eff_y - y;
				PlaySeDispCheck(hx, hy, SE_STEAL_HIT, TRUE);
			}
		}
	}

	//旗取れないＳＥ
	{
		u8 se_bit;
		se_bit = (parent->St3>>19) & 0xf;		//4ビットマスク
		se_bit = (se_bit >> my_net_id) & 0x1;			//1ビットマスク
		if (se_bit){
			Snd_SePlayEx( SE_STEAL_FLAG_NG, SE_PLAYER_MINE );
		}
	}

	//砂煙エフェクト表示
	{
		u8 snd_eff;
		snd_eff = (parent->St2 >> 18) & 0x1;		//1ビットマスク
		if (snd_eff){
			int eff_x,eff_y;
			eff_x = (parent->St2) & 0x1ff;		//9ビットマスク
			eff_y = (parent->St2>>9) & 0x1ff;		//9ビットマスク

			//座標保存
			ptr->SndX[ptr->SndEffIdx] = eff_x;
			ptr->SndY[ptr->SndEffIdx] = eff_y;

			//アニメ
			PkthlnClAct_SetActive(ptr->SndActPtr[ptr->SndEffIdx], 1, 1);
			PkthlnClAct_ChgAnm(ptr->SndActPtr[ptr->SndEffIdx], 4);

			//インデックス変更
			ptr->SndEffIdx = (ptr->SndEffIdx+1)%SND_EFFECT_NUM;

			//SE
			{
				int sx,sy;
				sx = START_POKE_POS_X + eff_x - x;
				sy = START_POKE_POS_Y + eff_y - y;
				PlaySeDispCheck(sx, sy, SE_STEAL_SAND_EFF, TRUE);
			}
		}
	}
	//ヒットエフェクト座標変更
	for(i=0;i<HIT_EFFECT_NUM;i++){
		VecFx32 hit_vec = {0,0,0};
		disp_x = START_POKE_POS_X + ptr->HitX[i] - x;
		disp_y = START_POKE_POS_Y + ptr->HitY[i] - y;
		//座標セット
		hit_vec.x = disp_x * FX32_ONE;
		hit_vec.y = disp_y * FX32_ONE;
		PkthlnClAct_SetPos(ptr->HitActPtr[i], &hit_vec);	//ヒットエフェクト
	}
	//砂煙エフェクト座標変更
	for(i=0;i<SND_EFFECT_NUM;i++){
		VecFx32 snd_vec = {0,0,0};
		disp_x = START_POKE_POS_X + ptr->SndX[i] - x;
		disp_y = START_POKE_POS_Y + ptr->SndY[i] - y;
		//座標セット
		snd_vec.x = disp_x * FX32_ONE;
		snd_vec.y = disp_y * FX32_ONE;
		PkthlnClAct_SetPos(ptr->SndActPtr[i], &snd_vec);	//砂煙エフェクト
	}

	//エフェクトプライオリティセット
	SetEffPriority(ptr);

	//親判定
	if (inMyNetID == COMM_PARENT_ID){
		is_parent = TRUE;
	}else{
		is_parent = FALSE;
	}

	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		VecFx32 vec;
		POKE_ACT_PTR poke_ptr;
		BOOL npc;
		u8 dir;
		u8 stl_poke_idx;
		u8 pause;
		u8 idx;
		u8 state;
		STL_POKE *stl_poke;

		int other_x, other_y;

		stl_poke = &inPokeList[i];

		other_x = parent->St1[i] & 0x1ff;	//9ビットマスク
		other_y = (parent->St1[i]>>9) & 0x1ff;	//9ビットマスク

		stl_poke_idx = (parent->St4[i]>>5) & 0x3;	//2ビットマスク
		dir = (parent->St4[i]>>7) & 0x3;	//2ビットマスク
		dir += 1;		//丸め込みを元に戻す
		state = (parent->St4[i]>>9) & 0x1;	//1ビットマスク


		pause = (parent->St2>>19) & 0xf;		//4ビットマスク
		pause = (pause >> i) & 0x1;	//1ビットマスク

		poke_ptr = inPokeList[i].PokeActPtr[stl_poke_idx];

		//NPC判定
		if ( PTFrame_GetPlayerNum(work) <= i ){
			npc = TRUE;
			child_data = PKTHLN_CommPack_GetData(&commData->ReciveData[i]);
		}else{
			npc = FALSE;
			child_data = PKTHLN_CommPack_GetData(&commData->SendData);
		}
		if (inMyNetID == i){	//デモ要求が自分自身
			ChangeDemo(ptr->SubDispCntPtr, &inPokeList[i], parent,
				i, stl_poke_idx, child_data,is_parent, TRUE, FALSE);	//<<ＮＰＣなわけがない。FALSE固定
		}else{					//デモ要求が他者
			ChangeDemo(ptr->SubDispCntPtr, &inPokeList[i], parent,
				i, stl_poke_idx, child_data,is_parent, FALSE, npc);
		}

		//相対距離を算出
		len_x = other_x - x;
		len_y = other_y - y;
		disp_x = START_POKE_POS_X + len_x;
		disp_y = START_POKE_POS_Y + len_y + inPokeList[i].DemoOfsY;

		vec.x = disp_x * FX32_ONE;
		vec.y = disp_y * FX32_ONE;
		vec.z = 0;

		//サブ画面アイコン描画
		StlSub_SetDrawSubDispIcon(ptr->SubDispCntPtr, i, stl_poke_idx, pause, state);

		//自分がポーズ中ではない　ＯＲ　自分ではない
		if ( !pause ){
			//表示範囲内かを判断
			if( ( ((DISP_X_MIN <= disp_x)&&(disp_x <= DISP_X_MAX))||
				  ((DISP_Y_MIN <= disp_y)&&(disp_y <= DISP_Y_MAX)) ) ){		//表示
				PokeAct_DispCnt(poke_ptr, TRUE);
			}else{		//非表示
				PokeAct_DispCnt(poke_ptr, FALSE);
			}
		}

		for(j=0;j<ENTRY_MAX;j++){
			POKE_ACT_PTR my_poke_ptr;
			my_poke_ptr = inPokeList[i].PokeActPtr[j];
			//座標セット
			PokeAct_SetPosShadow(my_poke_ptr, disp_x, disp_y);	//ポケ
		}

		{
			const PKTHPOKE_PARAM * prm;
			VecFx32 mat = {0,0,0};
			mat.x = disp_x * FX32_ONE;
			mat.y = disp_y * FX32_ONE;
			//タッチタイプで汗の位置かえる
			prm = PTFrame_GetPkthlnParam(work, i, stl_poke_idx);
			if (prm->Cell){
				mat.y -= (24*FX32_ONE);
			}else{
				mat.y -= (16*FX32_ONE);
			}
			PkthlnClAct_SetPos(inPokeList[i].StateActPtr, &mat);	//ステート
		}

		//プライオリティセット
		SetPokePriority(&inPokeList[i], disp_y);

		if ( !pause ){		//ポーズ中ではない
			u8 panic_flg = 0;
			//ステート表示
			if (state == POKE_ST_PANIC){
				if (inPokeList[i].StateLocal != state){
					PkthlnClAct_SetActive(inPokeList[i].StateActPtr, 1, 1);
				}
				//ポケのアニメ変更(気絶状態)
				PokeAct_SetAnm(poke_ptr, ANM_TYPE_PANIC_MORE);
				panic_flg = 1;
				//小ジャンプカウンタクリア
				stl_poke->LocalFlgGetCount = 0;
				//気絶ＳＥ ずっとコールさせる
				if (my_net_id == i){
					//"自分のPLAYER"でSE再生終了したかチェック
					if( Snd_SePlayCheckByPlayerNo(SE_PLAYER_MINE) == FALSE ){
						PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_THLON_RUNNING_OUT, TRUE);
					}
				}else{
					//"自分以外のPLAYER"でSE再生終了したかチェック
					if( Snd_SePlayCheckByPlayerNo(SE_PLAYER_OTHERS) == FALSE ){
						PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_THLON_RUNNING_OUT, FALSE);
					}
				}
			}else{
				PkthlnClAct_SetActive(inPokeList[i].StateActPtr, 1, 0);
			}

			//気絶でないときは、歩行アニメ
			if (!panic_flg){
				PokeAct_SetDirDatOnly(poke_ptr, dir);
				//小ジャンプカウンタが０ではないとき、小ジャンプアニメ
				if (stl_poke->LocalFlgGetCount>0){
					PokeAct_SetAnm(poke_ptr, ANM_TYPE_SJUMP);
					stl_poke->LocalFlgGetCount--;
				}else{
					PokeAct_SetAnm(poke_ptr, ANM_TYPE_WALK);
				}
			}
		}else{		//ポーズ中
			PkthlnClAct_SetActive(inPokeList[i].StateActPtr, 1, 0);
			PokeAct_SetDir(poke_ptr, dir);
		}
		inPokeList[i].StateLocal = state;

		//旗数表示
		{
			u8 flag_num;
			flag_num = (parent->St1[i] >> 28) & 0xf;		//4ビットマスク
			StlSub_SetFlagNum( ptr->SubDispCntPtr, i, flag_num );

			if (stl_poke->LocalFlgNum < flag_num){
				//ポケ小ジャンプアニメ状態(小ジャンプカウンタセット)
				stl_poke->LocalFlgGetCount = 10;
				//アニメ
				PkthlnClAct_ChgAnm(stl_poke->FlgGetActPtr, 8);
				PkthlnClAct_SetActive(stl_poke->FlgGetActPtr, 1, 1);
				//旗取得SE
				if (my_net_id == i){	//自分
					PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_STEAL_FLAG, TRUE);
				}else{					//他人
					PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_STEAL_FLAG_ENEMY, FALSE);
				}
			}else if((!pause)&&(stl_poke->LocalFlgNum > flag_num)){		//旗紛失
				//アニメ
				PkthlnClAct_ChgAnm(stl_poke->FlgGetActPtr, 9);
				PkthlnClAct_SetActive(stl_poke->FlgGetActPtr, 1, 1);

			}
			stl_poke->LocalFlgNum = flag_num;
			//座標をポケのところにする
			PkthlnClAct_SetPos(stl_poke->FlgGetActPtr, &vec);
		}

		//ポイントゲット
		{
			u8 p;
			u16 point;

			point = (parent->St1[i] >> 18) & 0x3ff;		//10ビットマスク

			if (inMyNetID == i){
				//得点フィル
				StlSub_FillPoint(ptr->SubDispCntPtr, point);
			}

			//ポイントゲットエフェクト
			if (stl_poke->DispPoint < point){
				//アニメ
				PkthlnClAct_ChgAnm(stl_poke->PtActPtr[stl_poke->PtActIdx], 3);
				PkthlnClAct_SetActive(stl_poke->PtActPtr[stl_poke->PtActIdx], 1, 1);
				stl_poke->PtActIdx = (stl_poke->PtActIdx+1)%PT_ACT_NUM;
				//サブ画面
				StlSub_StartPtGetAnm(ptr->SubDispCntPtr, i);
				//ポイント取得SE
				if (my_net_id == i){	//自分
					PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_STEAL_GOAL_POINT, TRUE);
				}else{					//他人
					PlaySeDispCheck(vec.x/FX32_ONE, vec.y/FX32_ONE, SE_STEAL_GOAL_POINT_ENEMY, FALSE);
				}

			}
			//ポイントゲット座標更新
			for(p=0;p<PT_ACT_NUM;p++){
				//座標をポケのところにする
				PkthlnClAct_SetPos(stl_poke->PtActPtr[p], &vec);
			}
			stl_poke->DispPoint = point;
		}
	}	//end for
}

//----------------------------------------------------------------------------
/**
 *	@brief	自分のポケの表示位置から相対的に考えて、障害物の配置を行う
 *
 *  @param	ptr			競技ポインタ
 *  @param	inPokeX		X座標
 *	@param	inPokeY		Y座標
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void CalcObstDispPos(PKTHLN_STL_PTR ptr, const int inPokeX, const int inPokeY)
{
	u8 i;
	//全障害物の座標を見て描画するかを決める
	for(i=0;i<OBST_NUM_MAX;i++){
		//障害物データ取得
		if (ptr->Obst[i].Valid){
			VecFx32 vec;
			int disp_x, disp_y;

			disp_x = START_POKE_POS_X + (ptr->Obst[i].X - inPokeX);
			disp_y = START_POKE_POS_Y + (ptr->Obst[i].Y - inPokeY);

			//座標セット
			vec.z = 0;
			vec.x = disp_x*FX32_ONE;
			vec.y = disp_y*FX32_ONE;

			PkthlnClAct_SetPos(ptr->Obst[i].ActPtr, &vec);
			//表示範囲内かを判断
			if( ((DISP_X_MIN <= disp_x)&&(disp_x <= DISP_X_MAX))&&
			((DISP_Y_MIN <= disp_y)&&(disp_y <= DISP_Y_MAX)) ){		//表示
				PkthlnClAct_SetActive(ptr->Obst[i].ActPtr, 1, 1);
			}else{		//非表示
				PkthlnClAct_SetActive(ptr->Obst[i].ActPtr, 1, 0);
			}
		}else{
			break;
		}
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	自分のポケの表示位置から相対的に考えて、障害物(パラソル)の配置を行う
 *
 *  @param	ptr			競技ポインタ
 *  @param	inPokeX		X座標
 *	@param	inPokeY		Y座標
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void CalcParasolDispPos(PKTHLN_STL_PTR ptr, const int inPokeX, const int inPokeY)
{
	u8 i;
	//全障害物の座標を見て描画するかを決める
	for(i=0;i<PARASOL_NUM_MAX;i++){
		//障害物データ取得
		if (ptr->Parasol[i].Valid){
			VecFx32 vec;
			int disp_x, disp_y;

			disp_x = START_POKE_POS_X + (ptr->Parasol[i].X - inPokeX);
			disp_y = START_POKE_POS_Y + (ptr->Parasol[i].Y - inPokeY);

			//座標セット
			vec.z = 0;
			vec.x = disp_x*FX32_ONE;
			vec.y = disp_y*FX32_ONE;

			PkthlnClAct_SetPos(ptr->Parasol[i].PoleActPtr, &vec);
			PkthlnClAct_SetPos(ptr->Parasol[i].RoofActPtr, &vec);
			//表示範囲内かを判断
			if( ((DISP_X_MIN <= disp_x)&&(disp_x <= DISP_X_MAX))&&
			((DISP_Y_MIN <= disp_y)&&(disp_y <= DISP_Y_MAX)) ){		//表示
				PkthlnClAct_SetActive(ptr->Parasol[i].PoleActPtr, 1, 1);
				PkthlnClAct_SetActive(ptr->Parasol[i].RoofActPtr, 1, 1);
			}else{		//非表示
				PkthlnClAct_SetActive(ptr->Parasol[i].PoleActPtr, 1, 0);
				PkthlnClAct_SetActive(ptr->Parasol[i].RoofActPtr, 1, 0);
			}
		}else{
			break;
		}
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	自分のポケの表示位置から相対的に考えて、旗の配置を行う
 *
 *  @param	ptr			競技ポインタ
 *  @param	parent		親通信データ
 *  @param	inPokeX		X座標
 *	@param	inPokeY		Y座標
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void CalcFlagDispPos(PKTHLN_STL_PTR ptr, STL_PARENT_DATA *parent, const int inPokeX, const int inPokeY)
{
	u8 i;

	//旗の座標を見て描画するかを決める
	for(i=0;i<FLAG_DISP_MAX;i++){
		int f_idx;
		int disp_x, disp_y;
		VecFx32 vec;
		//旗の座標を取得
		f_idx = parent->St4[i] & 0x1F;		//5ビットマスク

		disp_x = START_POKE_POS_X + (ptr->FlagData.FlgPos[f_idx].x-inPokeX);
		disp_y = START_POKE_POS_Y + (ptr->FlagData.FlgPos[f_idx].y-inPokeY);

		//座標セット
		vec.z = 0;
		vec.x = disp_x*FX32_ONE;
		vec.y = disp_y*FX32_ONE;
		PkthlnClAct_SetPos(ptr->FlagData.Flag[i].ActPtr, &vec);
		PkthlnClAct_SetPos(ptr->FlagData.Flag[i].EffActPtr, &vec);
		//表示範囲内かを判断
		if( ((DISP_X_MIN <= disp_x)&&(disp_x <= DISP_X_MAX))&&
			((DISP_Y_MIN <= disp_y)&&(disp_y <= DISP_Y_MAX)) ){		//表示
			PkthlnClAct_SetActive(ptr->FlagData.Flag[i].ActPtr, 1, 1);
			PkthlnClAct_SetActive(ptr->FlagData.Flag[i].EffActPtr, 1, 1);
		}else{		//非表示
			PkthlnClAct_SetActive(ptr->FlagData.Flag[i].ActPtr, 1, 0);
			PkthlnClAct_SetActive(ptr->FlagData.Flag[i].EffActPtr, 1, 0);
		}

		if (ptr->LocalFlagIdx[i] != f_idx){
			//旗出現エフェクト（煙）
			PkthlnClAct_ChgAnm(ptr->FlagData.Flag[i].EffActPtr, 4);
			//旗座標保存
			ptr->LocalFlagIdx[i] = f_idx;
		}

		//プライオリティセット
		SetFlagPriority(&ptr->FlagData.Flag[i], disp_y);
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief		ポケモン交代アニメ画面下にはける
 *
 *  @parm	sub_ptr			サブ画面コントローラポインタ
 *  @param	stl_poke		競技ポケモン
 *  @param	inNetID			ネットID
 *  @param	inStlPokeIdx	ポケモンインデックス
 *  @param	outChildData	子通信データ
 *  @param	inReqNpcMv		NPC動作か？
 *	@param	inReqSubDemo	サブ画面デモリクエストか？
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MoveDownAnm(STL_SUB_CNT_PTR sub_ptr, STL_POKE *stl_poke,
						const u8 inNetID, const u8 inStlPokeIdx, STL_CHILD_DATA *outChildData,
						const BOOL inReqNpcMv, const BOOL inReqSubDemo)
{
	switch(stl_poke->ChgSeq){
	case 0:
		//カウンタ初期化
		stl_poke->PokeMvCount = 0;
		//シーケンスチェンジ
		stl_poke->ChgSeq++;
		break;
	case 1:
		{
			int i;
			//ポケ座標変更
			stl_poke->DemoOfsY += DEMO_MOVE_Y;
			stl_poke->PokeMvCount++;
			if (stl_poke->PokeMvCount >= POKE_MOVE_COUNT){	//目標到達？
				//ポケ隠す
				PokeAct_DispCnt(stl_poke->PokeActPtr[inStlPokeIdx], 0);
				//シーケンスチェンジ
				stl_poke->ChgSeq++;
			}
		}
		break;
	case 2:
		//自分のポケならば、上画面の表示変更デモ
		if (inReqSubDemo){
			if (StlSub_PokeChangeMain(sub_ptr, inStlPokeIdx)){
				//ポケ上移動を親に通達
				outChildData->ChgState = CHILD_CHG_DOWN_END;
				stl_poke->ChgSeq++;
			}
		}else{
			if (inReqNpcMv){	//ＮＰＣ動作要求
				//ダミースライド関数
				if (StlSub_NpcPokeChangeMain(sub_ptr, inNetID)){
					//ポケ上移動を親に通達
					outChildData->ChgState = CHILD_CHG_DOWN_END;
					stl_poke->ChgSeq++;
				}
			}else{
				stl_poke->ChgSeq++;
			}
		}
		break;
	case 3:
		//待機
		break;
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief		ポケモン交代アニメ画面戻ってくる
 *
 *  @param	stl_poke		競技ポケモン
 *  @param	inNetID			ネットID
 *  @param	inStlPokeIdx	ポケモンインデックス
 *  @param	outChildData	子通信データ
 *  @param	inReqSend		親に終了を送信するか？
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MoveUpAnm(STL_POKE *stl_poke,
						const u8 inNetID, const u8 inStlPokeIdx, STL_CHILD_DATA *outChildData,
						const BOOL inReqSend)
{
	switch(stl_poke->ChgSeq){
	case 0:
		//カウンタ初期化
		stl_poke->PokeMvCount = 0;
		//ポケ出現
		PokeAct_DispCnt(stl_poke->PokeActPtr[inStlPokeIdx], 1);
		//シーケンスチェンジ
		stl_poke->ChgSeq++;
		break;
	case 1:
		{
			//ポケ座標変更
			stl_poke->DemoOfsY -= DEMO_MOVE_Y;
			stl_poke->PokeMvCount++;
			if (stl_poke->PokeMvCount >= POKE_MOVE_COUNT){	//目標到達？
				stl_poke->DemoOfsY = 0;
				//シーケンスチェンジ
				stl_poke->ChgSeq++;
			}
		}
		break;
	case 2:
		if (inReqSend){
			//ポケ上移動終了を親に通達
			outChildData->ChgState = CHILD_CHG_UP_END;
		}
		//シーケンスチェンジ
		stl_poke->ChgSeq++;
	case 3:
		//待機
		break;
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief		ポケモン交代アニメ画面下にはける
 *
 *  @parm	sub_ptr			サブ画面コントローラポインタ
 *  @param	stl_poke		競技ポケモン
 *  @param	parent			親通信データ
 *  @param	inNetID			ネットID
 *  @param	inStlPokeIdx	ポケモンインデックス
 *  @param	outChildData	子通信データ
 *  @param	inIsParent		親か？
 *	@param	inReqSubDemo	サブ画面デモリクエストか？
 *	@param	inIsNPC			NPCか？
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void ChangeDemo(STL_SUB_CNT_PTR sub_ptr,	STL_POKE *stl_poke,
						const STL_PARENT_DATA *inParent, const u8 inNetID,
						const u8 inStlPokeIdx, STL_CHILD_DATA *outChildData,
						const BOOL inIsParent, const BOOL inReqSubDemo, const BOOL inIsNPC)
{
	u8 chg_st;
	chg_st = (inParent->St2 >> 23) & 0xff;		//2*4ビットマスク
	chg_st = (chg_st >> (inNetID*2)) & 0x3;	//2ビットマスク

	//ステート検出
	if (stl_poke->ChgStateLocal != chg_st){	//ローカルステート差異がある場合
		//ステート更新
		stl_poke->ChgStateLocal = chg_st;
		//シーケンサ初期化
		stl_poke->ChgSeq = 0;
	}

	//デモシーケンス
	switch(stl_poke->ChgStateLocal){
	case CHG_MOVE_DOWN:
		{
			BOOL npc_mv;
			if (inIsParent&&inIsNPC){	//自分が親で、デモ要求がＮＰＣ
				npc_mv = TRUE;
			}else{
				npc_mv = FALSE;
			}
			MoveDownAnm(sub_ptr, stl_poke,
						inNetID, inStlPokeIdx, outChildData,
						npc_mv, inReqSubDemo	);
		}
		break;
	case CHG_MOVE_UP:
		{
			BOOL req_send;
			BOOL npc_mv;
			if (inIsParent&&inIsNPC){	//自分が親で、デモ要求がＮＰＣ
				npc_mv = TRUE;
			}else{
				npc_mv = FALSE;
			}

			//ＮＰＣ動作要求かサブ画面デモ要求があった場合は、親に終了を送る必要がある
			req_send = npc_mv | inReqSubDemo;
			MoveUpAnm(stl_poke, inNetID, inStlPokeIdx, outChildData, req_send);
		}
		break;
	case CHG_MOVE_NONE:
		break;
	}
}

//--------------------------------------------------------------------------------------------
/**
 * パラメータセット
 *
 * @param	work		ポケスロンワークポインタ
 * @param	*inData		パラメータ
 * @param	inNetID		ネットＩＤ
 * @param	inIdx		ポケモンエントリーインデックス0〜2
 * @param	*outPoke	パラメータ格納場所
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetPokeParam(	PKTHLN_PTR work, const STL_PARAM *inData,
							const u8 inNetID, const u8 inIdx, STL_POKE *outPoke)
{
	const POKE_SPEC *spec;
	spec = PTFrame_GetPokeSpec(work, inNetID, inIdx);

	outPoke->Param[inIdx].Power = (float)inData->Power[spec->Power]/10.0;
	outPoke->Param[inIdx].SpeedMax = inData->Speed[spec->Speed];
	outPoke->Param[inIdx].Accel1 = (float)inData->Accel1[spec->Technique]/10.0;
	outPoke->Param[inIdx].Accel2 = (float)inData->Accel2[spec->Speed]/10.0;
	outPoke->Param[inIdx].PanicTime = (int)inData->Panic[spec->Stamina];
}

//----------------------------------------------------------------------------
/**
 *	@brief		衝突判定すべき障害物のリストを作成する
 *
 *  @parm	ptr				コントローラ
 *  @param	inX				X座標
 *  @param	inY				Y座標
 *  @param	outObstList		障害物リストポインタ
 *  @param	outObstNum		障害物数
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MakeObstList(PKTHLN_STL_PTR ptr, const fx32 inX, const fx32 inY,
		OBJ_POS **outObstList, u8 *outObstNum)
{
	int i;
	int x,y;
	//リストのクリア
	for(i=0;i<OBST_NUM_MAX;i++){
		outObstList[i] = NULL;
	}

	//リストカウンタ初期化
	*outObstNum = 0;

	x = inX / FX32_ONE;
	y = inY / FX32_ONE;

	//全障害物の座標を見て描画するかを決める
	for(i=0;i<OBST_NUM_MAX;i++){
		//障害物データ取得
		if (ptr->Obst[i].Valid){
			VecFx32 vec;
			int disp_x, disp_y;
			disp_x = START_POKE_POS_X + (ptr->Obst[i].X - x);
			disp_y = START_POKE_POS_Y + (ptr->Obst[i].Y - y);

			//表示範囲内かを判断
			if( ((DISP_X_MIN <= disp_x)&&(disp_x <= DISP_X_MAX)) &&
				((DISP_Y_MIN <= disp_y)&&(disp_y <= DISP_Y_MAX)) ){		//画面内
				//リストに追加
				outObstList[(*outObstNum)++] = &ptr->ObstPos[i];
			}
		}else{
			break;
		}
	}
#ifdef PM_DEBUG
	if (debug_print){
		OS_Printf("判定する障害物の数は%d個\n",*outObstNum);
		for(i=0;i<*outObstNum;i++){
			u16 y;
			u16 x;
			y = ((*outObstList[i]).y);
			x = ((*outObstList[i]).x);
			OS_Printf("check_obst = %d_%d\n",x, y);
		}
	}
#endif
}

//----------------------------------------------------------------------------
/**
 *	@brief	障害物の衝突データを作成
 *
 *  @parm	inRange			範囲
 *  @param	inObstData		障害物データ
 *  @param	outHitData		ヒットデータ格納バッファ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void MakeHitData( const int inRange, const OBJ_POS *inObstData, S_OBST_HIT_DATA *outHitData)
{
	u32 y;
	u32 x;
	u32 width;
	u32 range;
	x = inObstData->x;
	y = inObstData->y;

	range = inRange;

#ifdef PM_DEBUG
	if (debug_print){
		OS_Printf("check_obst = %d_%d\n",x, y);
	}
#endif

	//障害物幅を決定
	width = OBST_WALL_WIDTH;
	x -= (width/2);
	y -= (width/2);
	//4頂点格納
	outHitData->Vrt[0].x = x;
	outHitData->Vrt[0].y = y;
	outHitData->Vrt[1].x = x+width;
	outHitData->Vrt[1].y = y;
	outHitData->Vrt[2].x = x+width;
	outHitData->Vrt[2].y = y+width;
	outHitData->Vrt[3].x = x;
	outHitData->Vrt[3].y = y+width;
	//4線分格納
	outHitData->Seg[0].Srt = outHitData->Vrt[0];
	outHitData->Seg[0].End = outHitData->Vrt[1];
	outHitData->Seg[1].Srt = outHitData->Vrt[1];
	outHitData->Seg[1].End = outHitData->Vrt[2];
	outHitData->Seg[2].Srt = outHitData->Vrt[2];
	outHitData->Seg[2].End = outHitData->Vrt[3];
	outHitData->Seg[3].Srt = outHitData->Vrt[3];
	outHitData->Seg[3].End = outHitData->Vrt[0];
	//境界ボリューム分の足しこみ
	outHitData->Seg[0].Srt.y -= range;
	outHitData->Seg[0].End.y -= range;
	outHitData->Seg[1].Srt.x += range;
	outHitData->Seg[1].End.x += range;
	outHitData->Seg[2].Srt.y += range;
	outHitData->Seg[2].End.y += range;
	outHitData->Seg[3].Srt.x -= range;
	outHitData->Seg[3].End.x -= range;

#ifdef PM_DEBUG
	if (debug_print){
		int i;
		OS_Printf("境界ボリュームを加味した結果\n");
		for(i=0;i<4;i++){
			OS_Printf("VERT%d = (%d,%d)\n", i,
					outHitData->Vrt[i].x, outHitData->Vrt[i].y);
			OS_Printf("SEG%d = (%d,%d)>(%d,%d)\n", i,
					outHitData->Seg[i].Srt.x, outHitData->Seg[i].Srt.y,
					outHitData->Seg[i].End.x, outHitData->Seg[i].End.y);
			OS_Printf("DIGI_SEG%d = (%d,%d)>(%d,%d)\n", i,
					outHitData->Seg[i].Srt.x/*/FX32_ONE*/, outHitData->Seg[i].Srt.y/*/FX32_ONE*/,
					outHitData->Seg[i].End.x/*/FX32_ONE*/, outHitData->Seg[i].End.y/*/FX32_ONE*/);
		}
	}
#endif
}

//----------------------------------------------------------------------------
/**
 *	@brief	障害物とのヒット判定
 *
 *  @param	inSrt			始点座標
 *  @param	inEnd			終端座標
 *  @parm	inRange			範囲
 *  @param	inHitData		ヒットデータ
 *  @param	outCross		交差座標
 *
 *	@return HIT_RC			ヒットコード
 */
//-----------------------------------------------------------------------------
static HIT_RC HitObst(const VecFx32 *inSrt, const VecFx32 *inEnd, const int inRange,
		const S_OBST_HIT_DATA *inHitData, VecFx32 *outCross )
{
	int i;
	Vec2DS32 cross;

	{								//障害物が壁
		Vec2DS32 srt,end;
		srt.x = inSrt->x/FX32_ONE;
		srt.y = inSrt->y/FX32_ONE;
		end.x = inEnd->x/FX32_ONE;
		end.y = inEnd->y/FX32_ONE;
		//線分交差判定
		for (i=0;i<4;i++){
			const HIT_RC hit_rc[4] = {HIT_RC_UWALL, HIT_RC_RWALL, HIT_RC_DWALL, HIT_RC_LWALL};
			int rc;
			rc = CheckCrossMatrix(
					(Vec2DS32 *)&inHitData->Seg[i].Srt,
					(Vec2DS32 *)&inHitData->Seg[i].End,
					&srt, &end,
					&cross );
			if (rc){
				outCross->x = cross.x * FX32_ONE;
				outCross->y = cross.y * FX32_ONE;
				outCross->z = 0;
				OS_Printf("hit_type = %d\n",hit_rc[i]);
				return hit_rc[i];
			}else{
				int hit = 0;
				//既に線分上にいるかを調べる
				if ( (i==0)&&(i==2) ){		//上or下
					if ( inHitData->Seg[i].Srt.y == srt.y ){
						s32 srt_x,end_x;
						if ( inHitData->Seg[i].Srt.x < inHitData->Seg[i].End.x ){
							srt_x = inHitData->Seg[i].Srt.x;
							end_x = inHitData->Seg[i].End.x;
						}else{
							srt_x = inHitData->Seg[i].End.x;
							end_x = inHitData->Seg[i].Srt.x;
						}
						if ( (srt_x <= srt.x)&&(srt.x <= end_x) ){
							hit = 1;
						}
					}
				}else{						//左or右
					if ( inHitData->Seg[i].Srt.x == srt.x ){
						s32 srt_y,end_y;
						if ( inHitData->Seg[i].Srt.y < inHitData->Seg[i].End.y ){
							srt_y = inHitData->Seg[i].Srt.y;
							end_y = inHitData->Seg[i].End.y;
						}else{
							srt_y = inHitData->Seg[i].End.y;
							end_y = inHitData->Seg[i].Srt.y;
						}
						if ( (srt_y <= srt.y)&&(srt.y <= end_y) ){
							hit = 1;
						}
					}
				}
				if (hit){
///					OS_Printf("線分上\n");
					*outCross = *inSrt;
					return hit_rc[i];
				}
			}
		}

		//頂点ヒット判定
		for (i=0;i<4;i++){
			const HIT_RC hit_rc[4] = {HIT_RC_LU_VRT, HIT_RC_RU_VRT, HIT_RC_RD_VRT, HIT_RC_LD_VRT};
			//ポケ中心と頂点の距離を求める
			VecFx32 vert, dif;
			fx32 len;
			fx32 t;
			vert.x = inHitData->Vrt[i].x*FX32_ONE;
			vert.y = inHitData->Vrt[i].y*FX32_ONE;
			vert.z = 0;

			VEC_Subtract( inEnd, &vert, &dif );
			len = VEC_Mag(&dif);
#ifdef PM_DEBUG
			if (debug_print){
				OS_Printf("len%d\n",len);
			}
#endif
			if (len <= inRange*FX32_ONE){
				VecFx32 dir, dst;
				OS_Printf("頂点ヒット\n");
				t = CalcT(inSrt, inEnd, &vert , inRange*FX32_ONE);
				VEC_Subtract( inEnd, inSrt, &dir );
				VEC_MultAdd(t,&dir,inSrt,&dst);
				outCross->x = dst.x;
				outCross->y = dst.y;
				outCross->z = 0;
				OS_Printf("hit_type = %d\n",hit_rc[i]);
				return hit_rc[i];
			}
		}

		//矩形内ヒット判定
		if ( (inHitData->Vrt[0].x*FX32_ONE<=inEnd->x)&&(inEnd->x<=inHitData->Vrt[2].x*FX32_ONE) &&
			 (inHitData->Vrt[0].y*FX32_ONE<=inEnd->y)&&(inEnd->y<=inHitData->Vrt[2].y*FX32_ONE) ){

			HIT_RC rc;
			fx32 len1, len2;
			fx32 len_x, len_y;
			u8 h_hit,w_hit;
			u8 w, h;

			*outCross = *inEnd;
			h_hit = 0;
			w_hit = 0;

			OS_Printf("矩形内。押し出します\n");
			len1 = inHitData->Vrt[0].x*FX32_ONE - inEnd->x;
			len2 = inHitData->Vrt[2].x*FX32_ONE - inEnd->x;
			if (len1<0) len1*=(-1);
			if (len2<0) len2*=(-1);
			if (len1<len2){
				len_x = len1;
				//左あたり
				w = HIT_RC_LWALL_F;
			}else{
				len_x = len2;
				//右あたり
				w = HIT_RC_RWALL_F;
			}

			len1 = inHitData->Vrt[0].y*FX32_ONE - inEnd->y;
			len2 = inHitData->Vrt[2].y*FX32_ONE - inEnd->y;
			if (len1<0) len1*=(-1);
			if (len2<0) len2*=(-1);
			if (len1<len2){
				len_y = len1;
				//上あたり
				h = HIT_RC_UWALL_F;
			}else{
				len_y = len2;
				//下あたり
				h = HIT_RC_DWALL_F;
			}

			if ( len_x<=len_y){
				//横あたり
				w_hit = 1;
				rc = w;
			}else{
				//縦あたり
				h_hit = 1;
				rc = h;
			}
			if (w_hit){
				if (w==HIT_RC_LWALL_F){
					outCross->x = (inHitData->Vrt[0].x-inRange)*FX32_ONE;
				}else{
					outCross->x = (inHitData->Vrt[2].x+inRange)*FX32_ONE;
				}
			}else if (h_hit){
				if (h==HIT_RC_UWALL_F){
					outCross->y = (inHitData->Vrt[0].y-inRange)*FX32_ONE;
				}else{
					outCross->y = (inHitData->Vrt[2].y+inRange)*FX32_ONE;
				}
			}
			return rc;
		}

	}

	return HIT_RC_NONE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	障害物当たり判定
 *
 *  @param	ptr			コントローラ
 *  @param	inHitRc		ヒットコード
 *  @param	inRange		範囲
 *  @param	inSrt		始点座標
 *  @param	inEnd		終端座標
 *  @param	outVec		交点座標
 *
 *	@return u16			ヒットコード
 */
//-----------------------------------------------------------------------------
static u16 HitCheckObst(PKTHLN_STL_PTR ptr, const HIT_RC inHitRc, const int inRange,
		const VecFx32 *inSrt, const VecFx32 *inEnd, VecFx32 *outVec)
{
	u16 rc;
	int i;
	u8 obst_num;
	OBJ_POS *obst_list[OBST_NUM_MAX];

	u8 obst_hit;

#ifdef DEBUG_HIT_CHECK_IGNORE
	return 0;
#endif
#ifdef PM_DEBUG
	if (debug_print){
		OS_Printf("move_dir=(%d,%d)>(%d,%d)\n",
				inSrt->x/FX32_ONE, inSrt->y/FX32_ONE, inEnd->x/FX32_ONE, inEnd->y/FX32_ONE);
	}
#endif
	//障害物リスト作成
	MakeObstList(ptr, inSrt->x, inSrt->y, obst_list, &obst_num);

	//作成したリストの障害物と当たり判定を行う
	obst_hit = 0;
	for(i=0;i<obst_num;i++){
		S_OBST_HIT_DATA hit_data;

		HIT_RC hit_rc;
		VecFx32 cross;
		//あたりデータを作成
		MakeHitData( inRange, obst_list[i], &hit_data);

		//ヒット判定
		hit_rc = HitObst(inSrt, inEnd, inRange, &hit_data, &cross );

		if (hit_rc != HIT_RC_NONE){
			OS_Printf("hit::type=%d  pos =(%d,%d)\n",hit_rc, cross.x, cross.y);
			if (HIT_RC_UWALL_F <= hit_rc ){
				outVec->x = cross.x;
				outVec->y = cross.y;
				outVec->z = 0;
			}else if (hit_rc != inHitRc){
				outVec->x = cross.x;
				outVec->y = cross.y;
				outVec->z = 0;
			}
			obst_hit = hit_rc;
			break;
		}
	}

	rc = obst_hit;

	return rc;

}

//----------------------------------------------------------------------------
/**
 *	@brief	媒介変数ｔを求める関数(tは値の小さい方を求める。マイナスにはならないはず)
 *
 *  @param	inSrt		始点座標
 *  @param	inEnd		終端座標
 *  @param	inVrt		頂点
 *  @param	inC			変数
 *
 *	@return fx32		媒介変数
 */
//-----------------------------------------------------------------------------
static fx32 CalcT(const VecFx32 *inSrt, const VecFx32 *inEnd, const VecFx32 *inVrt , const fx32 inC)
{
	fx32 a,b,c;
	fx32 len;
	fx32 sqrt;
	VecFx32 vec;

	fx32 t1,t2, t;

	VEC_Subtract( inEnd, inSrt, &vec );
	len = VEC_Mag(&vec);
	a = len*len;

	b = VEC_DotProduct(&vec, inVrt);

	len = VEC_Mag(inVrt);
	c = (len*len) - (inC*inC);

	OS_Printf("abc = %d,%d,%d\n", a,b,c);

	sqrt = FX_Sqrt( b-(a*c) );
	t1 = -b + sqrt;
	t1 = FX_Div(t1,a);

	t2 = -b - sqrt;
	t2 = FX_Div(t2,a);

	OS_Printf("sqrt = %d,%d\n", t1,t2);

	if (t1 > t2){
		t = t2;
	}else{
		t = t1;
	}

	return t;
}

//----------------------------------------------------------------------------
/**
 *	@brief	最大スピードを求める
 *
 *  @param	poke				競技ポケモン
 *  @param	inStlPokeIdx		ポケモンインデックス
 *
 *	@return float		スピード
 */
//-----------------------------------------------------------------------------
static float GetMaxSpeed( STL_POKE *poke, const u8 inStlPokeIdx )
{
	return poke->Param[inStlPokeIdx].SpeedMax;
}

//----------------------------------------------------------------------------
/**
 *	@brief	スピード加算関数
 *
 *  @param	inSrtVec		始点座標
 *  @param	inAddVec		加算値
 *  @param	outDstVec		取得座標格納バッファ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void AddSpeedVec(const VecFx32 *inSrcVec, const VecFx32 *inAddVec, VecFx32 *outDstVec)
{
	outDstVec->x = inSrcVec->x + inAddVec->x;
	outDstVec->y = inSrcVec->y + inAddVec->y;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモン同士の衝突
 *
 *  @param	work		ポケスロンワーク
 *  @param	pPokeList	競技ポケモンリスト
 *  @param	outvec		ヒット座標
 *
 *	@return BOOl		TRUEでヒット
 */
//-----------------------------------------------------------------------------
static BOOL HitCheckPoke(PKTHLN_PTR work, STL_POKE*	pPokeList, VecFx32 *outVec)
{
	int i,j;
	VecFx32 my_vec;
	VecFx32 target_vec;
	int my_range, target_range;
	POKE_ACT_PTR m_poke_ptr,  t_poke_ptr;
	BOOL hit_effect;

	hit_effect = FALSE;
	my_vec.z = 0;
	target_vec.z = 0;
	for(i=0;i<ENTRY_MEMBER_NUM_MAX;i++){
		STL_POKE *my_poke;
		int msx_org, msy;
		u8 my_idx;

		my_poke = &pPokeList[i];
		my_idx = my_poke->StlPokeIdx;

		//自分がポーズならスルー
		if(my_poke->Pause){
			continue;
		}

		m_poke_ptr = my_poke->PokeActPtr[my_idx];
		PokeAct_GetTouchPosByShadowPos(m_poke_ptr, my_poke->Pos.x/FX32_ONE, my_poke->Pos.y/FX32_ONE, &msx_org, &msy);

		for(j=0;j<ENTRY_MEMBER_NUM_MAX;j++){
			STL_POKE *target_poke;
			int tsx,tsy,msx;
			fx32 len, range;
			VecFx32 vec;

			if (i==j){		//自分同士は当たり判定しない
				continue;
			}

			target_poke = &pPokeList[j];

			//対象相手がポーズならスルー
			if(target_poke->Pause){
				continue;
			}

			msx = msx_org;

			t_poke_ptr = target_poke->PokeActPtr[target_poke->StlPokeIdx];

			PokeAct_GetTouchPosByShadowPos(t_poke_ptr,
					target_poke->Pos.x/FX32_ONE, target_poke->Pos.y/FX32_ONE, &tsx, &tsy);

			PokeAct_GetHitData(t_poke_ptr,
				tsx*FX32_ONE, tsy*FX32_ONE, &target_vec.x, &target_vec.y, &target_range);
			PokeAct_GetHitData(m_poke_ptr,
				msx*FX32_ONE, msy*FX32_ONE, &my_vec.x, &my_vec.y, &my_range);

			VEC_Subtract( &my_vec, &target_vec, &vec );
			len = VEC_Mag(&vec);
			range = (target_range + my_range)*FX32_ONE;

///			OS_Printf("%dと%dを比較。len=%d:rabge=%d\n",i,j,len,range);

			if ( len < range ){
				if (!my_poke->Hit[j]){
					BOOL rc;
					//後ろからの衝突かを調べる
					rc = CheckPanicHit(work, my_poke, target_poke);

					//気絶状態にできないヒットの場合はお互いに同じヒットポーズフレームをセットする
					if (!rc){
						//ヒットポーズ開始
						my_poke->HitFrame = HIT_FRAME_DMG;
						target_poke->HitFrame = HIT_FRAME_DMG;
					}

					//ゲーム最大速度は超えないようにする
					{
						fx32 len;
						len = VEC_Mag(&my_poke->Speed);
						if ( len > GAME_MAX_SPEED*FX32_ONE ){		//超えた
							VecFx32 add = {0,0,0};
							//正規化後GAME_MAX_SPEED倍
							VEC_Normalize(&my_poke->Speed, &my_poke->Speed);
							VEC_MultAdd(GAME_MAX_SPEED*FX32_ONE, &my_poke->Speed,
										&add, &my_poke->Speed);
						}
					}
					//ゲーム最大速度は超えないようにする
					{
						fx32 len;
						len = VEC_Mag(&target_poke->Speed);
						if ( len > GAME_MAX_SPEED*FX32_ONE ){		//超えた
							VecFx32 add = {0,0,0};
							//正規化後GAME_MAX_SPEED倍
							VEC_Normalize(&target_poke->Speed, &target_poke->Speed);
							VEC_MultAdd(GAME_MAX_SPEED*FX32_ONE, &target_poke->Speed,
										&add, &target_poke->Speed);
						}
					}

					GF_ASSERT(my_poke->Hit[j] == 0);
					GF_ASSERT(target_poke->Hit[i] == 0);
					//ヒット状態をON
					my_poke->Hit[j] = 1;
					target_poke->Hit[i] = 1;

					//ヒットエフェクト座標を計算
					if (!hit_effect ){
						VecFx32 vec = {0,0,0};
						fx32 r;
						hit_effect = TRUE;
						//自分からターゲットへのベクトル
						VEC_Subtract(&target_vec, &my_vec, &vec);
						//正規化
						VEC_Normalize(&vec, &vec);
						//自分の半径倍する
						r = my_range*FX32_ONE;
						VEC_MultAdd(r,&vec,&my_vec,&vec);
						*outVec = vec;
					}

					OS_Printf("ポケヒット\n");

					//アクションポイント加算「体当たり」
					PTFrame_AddActionPoint(	work, my_poke->NetID, my_poke->StlPokeIdx, ADD_TYPE_ATTACK, 1 );
					PTFrame_AddActionPoint(	work, target_poke->NetID, target_poke->StlPokeIdx, ADD_TYPE_ATTACK, 1 );
					break;
				}
			}else{
				//ヒットしてないので、ヒット状態をＯＦＦ
				if (my_poke->Hit[j]){
					OS_Printf("ヒットを解除%d_%d\n",i,j);
				}
				if (target_poke->Hit[i]){
					OS_Printf("ヒットを解除%d_%d\n",j,i);
				}
				my_poke->Hit[j] = 0;
				target_poke->Hit[i] = 0;
			}
		}
	}

	return hit_effect;
}

//----------------------------------------------------------------------------
/**
 *	@brief	ステートアクターの表示位置を決定しセットする
 *
 *  @param	inParam			ポケスロンポケモンパラメータ
 *  @param	inSdwPos		影座標
 *  @param	pStateActPtr	ステートアクター
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetStateActPos(	const PKTHPOKE_PARAM *inParam,
							const VecFx32 *inSdwPos,
							PKTHLN_ACT_PTR pStateActPtr )
{
	VecFx32 vec;
	vec = *inSdwPos;

	//シャドータイプを取得
	switch(inParam->Shadow){
	case SHADOW_TYPE_A:
		vec.y -= (20*FX32_ONE);
		break;
	case SHADOW_TYPE_B:
		vec.y -= (32*FX32_ONE);
		break;
	case SHADOW_TYPE_C:
		vec.y -= (40*FX32_ONE);
		break;
	default:
		GF_ASSERT(0);
	}

	PkthlnClAct_SetPos(pStateActPtr, &vec);
}

//----------------------------------------------------------------------------
/**
 *	@brief	Ｙ座標から障害物プライオリティーを決定する
 *
 *  @param	ptr		コントローラポインタ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetObjPriority(PKTHLN_STL_PTR ptr)
{
	int i;
	int pri;
	const VecFx32 *vec;
	//パラソル・ポール
	for(i=0;i<PARASOL_NUM_MAX;i++){
		int y;
		PkthlnClAct_SetPriority(ptr->Parasol[i].RoofActPtr, PRI_PARASOL);
		//ポールのＹ座標を取得
		vec = PkthlnClAct_GetPos(ptr->Parasol[i].PoleActPtr);
		y = vec->y / FX32_ONE;
		pri = GetOBJPriorityByY(y);
		PkthlnClAct_SetPriority(ptr->Parasol[i].PoleActPtr, pri+PRI_OFS_POLE);
	}
	//障害物
	for(i=0;i<OBST_NUM_MAX;i++){
		int y;
		vec = PkthlnClAct_GetPos(ptr->Obst[i].ActPtr);
		//障害物のＹ座標取得
		y = vec->y / FX32_ONE;
		pri = GetOBJPriorityByY(y);
		PkthlnClAct_SetPriority(ptr->Obst[i].ActPtr, pri+PRI_OFS_OBST);
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗のプライオリティセット
 *
 *  @param	flag		旗
 *  @param	inY			Y座標
 *
 *	@return none
 */
//-----------------------------------------------------------------------------

static void SetFlagPriority(STL_FLAG *flag, const int inY)
{
	int pri;
	pri = GetOBJPriorityByY(inY);
	PkthlnClAct_SetPriority(flag->ActPtr, pri+PRI_OFS_FLG);
	PkthlnClAct_SetPriority(flag->EffActPtr, pri+PRI_OFS_FLG_AP);
}

//----------------------------------------------------------------------------
/**
 *	@brief	エフェクトのプライオリティセット
 *
 *  @param	ptr			コントローラポインタ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetEffPriority(PKTHLN_STL_PTR ptr)
{
	int i;
	int pri;
	int y;
	const VecFx32 *vec;
	for(i=0;i<SND_EFFECT_NUM;i++){
		vec = PkthlnClAct_GetPos(ptr->SndActPtr[i]);
		//Ｙ座標取得
		y = vec->y / FX32_ONE;
		pri = GetOBJPriorityByY(y);
		PkthlnClAct_SetPriority(ptr->SndActPtr[i], pri+PRI_OFS_SND);
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	ポケモンのプライオリティセット
 *
 *  @param	poke		競技ポケモン
 *  @param	inY			Y座標
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetPokePriority(STL_POKE *poke, const int inY)
{
	int i;
	int pri;

	pri = GetOBJPriorityByY(inY);
	//ステート
	PkthlnClAct_SetPriority(poke->StateActPtr, pri+PRI_OFS_STATE);
	//ポケ
	for(i=0;i<ENTRY_MAX;i++){
		PokeAct_SetPriority(poke->PokeActPtr[i], pri+PRI_OFS_POKE);
	}
}

//----------レコードＢＭＰ---------------
//ＢＮＰウィンドウデータ
static const BMPWIN_DAT RecordBmpData = {
		REC_BG, WIN_REC_PX, WIN_REC_PY,
		WIN_REC_SX, WIN_REC_SY, REC_FONT_PAL, WIN_REC_CGX
};

//--------------------------------------------------------------------------------------------
/**
 * BMPウィンドウ追加
 *
 * @param 	ptr			コントローラポインタ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void CreateBmpWin( PKTHLN_STL_PTR ptr )
{
	const BMPWIN_DAT * dat = &RecordBmpData;

	GF_BGL_BmpWinAddEx( ptr->bgl, &ptr->Win, dat );

	//先頭キャラをクリア（スクリーンクリアされてるところは、このキャラで埋まる）
	GF_BGL_CharFill( ptr->bgl, REC_BG, 0, 1, 0 );

	//システム用フォントパレット転送
	SystemFontPaletteLoad(PALTYPE_MAIN_BG, REC_FONT_PAL*32, ptr->HeapID);
}

//----------------------------------------------------------------------------
/**
 *	@brief		レコード文字列展開
 *
 *	@param	ptr			コントローラポインタ
 *	@param	inRecord	記録
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void SetRecordStr(PKTHLN_STL_PTR ptr, const int inRecord)
{
	WORDSET *word;
	STRBUF * str;
	MSGDATA_MANAGER *msgman;
	int integer;

	GF_BGL_BmpWinDataFill( &ptr->Win, 0);

	//整数部分
	integer = inRecord;

	msgman = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_pokethlon_dat, ptr->HeapID);
    word = WORDSET_Create(ptr->HeapID);
	WORDSET_RegisterNumber(word, 0, integer, 3,
				NUMBER_DISPTYPE_LEFT,NUMBER_CODETYPE_DEFAULT);

    str = MSGDAT_UTIL_AllocExpandString(word, msgman, msg_pkthln_new_record02, ptr->HeapID);

	GF_STR_PrintColor( 	&ptr->Win, FONT_TOUCH, str,
					0, 0, MSG_NO_PUT, COL_N_WHITE, NULL );
	STRBUF_Delete(str);//<一括表示なので、メモリをここで消してもOK
	WORDSET_Delete( word );
	MSGMAN_Delete( msgman );

	GF_BGL_BmpWinOn(&ptr->Win);
}

//旗関連

//----------------------------------------------------------------------------
/**
 *	@brief	初期化
 *
 *  @param	ptr		コントローラ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void InitFlagData(PKTHLN_STL_PTR ptr)
{
	ptr->FlagData.FlgPosIdx = 0;
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗アクター座標インデックスのインクリメント
 *
 *  @param	pFlagData		旗データ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void IncFlagPosIdx(FLAG_DATA * pFlagData)
{
	pFlagData->FlgPosIdx = (pFlagData->FlgPosIdx+1)%FLAG_CONT_MAX;
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗アクターセット
 *
 *  @param	pFlagData			旗データ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void SetFlag(FLAG_DATA *pFlagData)
{
	int i;
	STL_FLAG *flag;
	flag = pFlagData->Flag;
	//空いている旗アクター検索
	for(i=0;i<FLAG_DISP_MAX;i++){
		if (flag[i].Valid){
			continue;
		}
		flag[i].Idx = pFlagData->FlgPosIdx;
		//AI参照のため座標を格納
		flag[i].X = pFlagData->FlgPos[ pFlagData->FlgPosIdx ].x;
		flag[i].Y = pFlagData->FlgPos[ pFlagData->FlgPosIdx ].y;
		//旗座標参照インデックスインクリメント
		IncFlagPosIdx(pFlagData);
		flag[i].Valid = TRUE;
		return;
	}

	GF_ASSERT(0);
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗ジェネレータ
 *
 *  @param	ptr		コントローラ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void GenerateFlag(PKTHLN_STL_PTR ptr)
{
	int i;
	int num;
	//(最大表示旗数-場の旗数)回ループ
	num = FLAG_DISP_MAX - ptr->FlagData.DispFlgNum;
	for(i=0;i<num;i++){
		//旗セット
		SetFlag(&ptr->FlagData);
		//場の旗数インクリメント
		ptr->FlagData.DispFlgNum++;
		GF_ASSERT(ptr->FlagData.DispFlgNum<=FLAG_DISP_MAX);
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗取得
 *
 * 	@param	pFlagData		旗データ
 *  @param	ioPoke			競技ポケモン
 *  @param	outSE			SEフラグ
 *
 *	@return BOOL			TRUEで取得
 */
//-----------------------------------------------------------------------------
static BOOL GetFlag(FLAG_DATA *pFlagData, STL_POKE *ioPoke, u8 *outSE)
{
	int i;
	*outSE = 0;
	//ポケモンの所持旗数を調べる
	//旗の取得判定
	for(i=0;i<FLAG_DISP_MAX;i++){
///		if (ioPoke->FlagNum >= FLAG_TAKE_MAiX){
///			return FALSE;
///		}
		if (pFlagData->Flag[i].Valid){
			BOOL rc;
			VecFx32 flag_pos;
			u8 poke_idx;
			flag_pos.x = pFlagData->FlgPos[pFlagData->Flag[i].Idx].x * FX32_ONE;
			flag_pos.y = pFlagData->FlgPos[pFlagData->Flag[i].Idx].y * FX32_ONE;
			flag_pos.z = 0;
			poke_idx = ioPoke->StlPokeIdx;
			rc = HitCheckCircle(&ioPoke->Pos, &flag_pos,
					PokeAct_GetHitRange(ioPoke->PokeActPtr[poke_idx])*FX32_ONE,
					FLAG_RANGE*FX32_ONE);
			if (rc){
				if (ioPoke->FlagNum >= FLAG_TAKE_MAX){
					//もう取れない
					if (!ioPoke->HitFlag[i]){
						//ＳＥフラグＯＮ
						*outSE = 1;
						//旗接触フラグセット
						ioPoke->HitFlag[i] = 1;
					}
					return FALSE;
				}
				//旗接触フラグセット
				ioPoke->HitFlag[i] = 1;
				//旗無効に
				pFlagData->Flag[i].Valid = FALSE;
				//旗取得
				ioPoke->FlagNum++;
				//表示旗減少
				GF_ASSERT(pFlagData->DispFlgNum>0);
				pFlagData->DispFlgNum--;
				return TRUE;
			}else{
				//旗接触フラグをクリア
				ioPoke->HitFlag[i] = 0;
			}
		}else{
			//旗接触フラグをクリア
			ioPoke->HitFlag[i] = 0;
		}
	}
	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	円同士の当たり判定
 *
 *  @param	inVec1		中心座標
 *  @param	inVec2		中心座標
 *  @param	inRange		半径
 *  @param	inRange		半径
 *
 *	@return BOOL		TRUEでヒット
 */
//-----------------------------------------------------------------------------
static BOOL HitCheckCircle(const VecFx32 *inVec1, const VecFx32 *inVec2,
		const fx32 inRange1, const fx32 inRange2)
{
	VecFx32 vec;
	VEC_Subtract( inVec1, inVec2, &vec);
	if ( VEC_Mag(&vec) < inRange1+inRange2 ){
		return TRUE;
	}
	return FALSE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	方向ベクトルからポケモンの向きを計算
 *
 *  @param	inVec		方向ベクトル
 *
 *	@return u8		方向
 */
//-----------------------------------------------------------------------------
static u8 CalcDir(const VecFx32 *inVec)
{
	u8 dir;
	VecFx32 norm_dir_vec;

	dir = POKE_DIR_UP;
	//正規化
	VEC_Normalize(inVec, &norm_dir_vec);
	if (VEC_Mag(&norm_dir_vec) != 0){
		//ZX平面で考える
		u16 rad;
		VecFx32 vec = {0,0,FX32_ONE};
		VecFx32 xz_vec;
		xz_vec.x = norm_dir_vec.y;
		xz_vec.z = norm_dir_vec.x;
		xz_vec.y = 0;

		rad = GetRad(&vec, &xz_vec);
		if ( (0<=rad&&rad<=0x2000)||(0xe000<=rad) ){		//右
			dir = POKE_DIR_RIGHT;
		}else if(0x2000<rad&&rad<0x6000){		//下
			dir = POKE_DIR_DOWN;
		}else if(0x6000<=rad&&rad<=0xa000){		//左
			dir = POKE_DIR_LEFT;
		}else{	//(0xa000<rad&&rad<0xe000)		//上
			dir = POKE_DIR_UP;
		}
	}
	return dir;
}

//----------------------------------------------------------------------------
/**
 *	@brief	気絶ヒット判定
 *
 *  @param	work		ポケスロンワーク
 *  @param	poke1		競技ポケモン
 *  @parm	poke2		競技ポケモン
 *
 *	@return BOOL		TRUEでヒット
 */
//-----------------------------------------------------------------------------
static BOOL CheckPanicHit(PKTHLN_PTR work, STL_POKE* poke1, STL_POKE* poke2)
{
	STL_POKE* push;
	STL_POKE* target;

	//スピードのある方を調べる
	fx32 len1, len2;
	len1 = VEC_Mag(&poke1->Speed);
	len2 = VEC_Mag(&poke2->Speed);
	if ( len1 > len2 ){
		push = poke1;
		target = poke2;
	}else if ( len1 < len2 ){
		push = poke2;
		target = poke1;
	}else {
		return FALSE;
	}

	//押される側のポケが押す側のポケと同じ向きかを調べる
	if ( push->Dir != target->Dir ){
		return FALSE;
	}

	//押す側のポケモンの向きとスピード向きが同じかを調べる
	if ( CalcDir(&push->Speed) != push->Dir ){
		return FALSE;
	}
	//押す側が気絶状態かを調べる
	if (push->State == POKE_ST_PANIC){
		return FALSE;
	}

	//後ろから押したとみなして、旗を奪う
	if (target->FlagNum>=STEAL_FLAG_NUM){
		target->FlagNum -= STEAL_FLAG_NUM;
		push->FlagNum += STEAL_FLAG_NUM;
	}else{
		push->FlagNum += target->FlagNum;
		target->FlagNum = 0;
	}

	//最大数オーバーチェック
	if (push->FlagNum > FLAG_TAKE_MAX){
		push->FlagNum = FLAG_TAKE_MAX;
	}

	//押された方は気絶状態になる
	target->State = POKE_ST_PANIC;
	//アクションポイント加算「失敗」
	PTFrame_AddActionPoint(	work, target->NetID, target->StlPokeIdx, ADD_TYPE_FAIL, 1 );
	//気絶時間設定
	{
		u8 idx;
		idx = target->StlPokeIdx;
		target->PanicCount = ((VEC_Mag(&push->Speed) * 1 ) / FX32_ONE ) + target->Param[idx].PanicTime;
		OS_Printf("気絶時間：%d\n",target->PanicCount);
	}

	{
		fx32 scalar;
		VecFx32 add = {0,0,0};
		u8 idx = push->StlPokeIdx;
		//あたられたポケはスピードをもらい、あたったポケはスピードを失う
		scalar = push->Param[idx].Power * FX32_ONE;
		OS_Printf("sc=%d::%f\n",scalar, push->Param[idx].Power);
		VEC_MultAdd( scalar, &push->Speed, &add, &target->Speed );
		push->Speed = add;		//スピードなし
	}

	//ヒットポーズ開始
	push->HitFrame = HIT_FRAME_ATK;
	target->HitFrame = HIT_FRAME_DMG;

	return TRUE;
}

//----------------------------------------------------------------------------
/**
 *	@brief  ゴール判定
 *
 *  @param	inPoke			競技ポケモン
 *
 *	@return BOOL		TRUEでゴール
 */
//-----------------------------------------------------------------------------
static BOOL CheckGoal(STL_POKE *inPoke)
{
	BOOL in = FALSE;

	//エリア判定
	if ( inPoke->Pos.y > CHANGE_Y_LIMIT_MAX * FX32_ONE ){
		if ( (GOAL_X_LIMIT_MIN * FX32_ONE <= inPoke->Pos.x)&&
				(inPoke->Pos.x <= GOAL_X_LIMIT_MAX * FX32_ONE) ){
			in = TRUE;
		}
	}

	//ゴールエリアにいるか？
	if (!in){
		return FALSE;		//エリア外
	}
	//旗持っているか？
	if (!inPoke->FlagNum){
		return FALSE;		//旗なしの場合はゴールとみなさない
	}
	//気絶してないか？
	if (inPoke->State != POKE_ST_NORMAL){
		return FALSE;		//状態異常の場合はゴールとみなさない
	}

	return TRUE;
}

//----------------------------------------------------------------------------
/**
 *	@brief	旗の数から得点を計算
 *
 *  @param	inFlagNum		旗の数
 *
 *	@return u8	得点
 */
//-----------------------------------------------------------------------------
static u8 CalcPointByGetFlag(const u8 inFlagNum)
{
	return inFlagNum;
}

//----------------------------------------------------------------------------
/**
 *	@brief	OBJのY座標からプライオリティ取得
 *
 *  @param	inY				Y座標
 *
 *	@return int				プライオリティ
 */
//-----------------------------------------------------------------------------
static int GetOBJPriorityByY(const int inY)
{
	int pri;
	//奥行きが同じとき、プライオリティを旗GET＞障害物＞砂煙＞ステート＞ポケ＞ポール＞旗出現煙＞旗
	//とするため1+1+1+1+1+1+1+1 = 8 単位でオフセットをつけていく
	pri = (DISP_HEIGHT - inY) * 8 + PRI_STL_BASE;
///	OS_Printf("プライオリティ:%d\n",pri);
	return pri;
}

//----------------------------------------------------------------------------
/**
 *	@brief	転送アニメ
 *
 *  @param	ptr		コントローラ
 *
 *	@return none
 */
//-----------------------------------------------------------------------------
static void TransAnmMain(PKTHLN_STL_PTR ptr)
{
	u8 *data;
	void *adr;

	if ( ptr->TrnsCount >= TRNS_ANM_TIMING ){
		data = (u8*)ptr->TransCharData->pRawData;
		adr = &data[ptr->TrnsAnmIdx*BG_ANM_CHAR_TRANS_SIZE];
		DC_FlushRange(adr, BG_ANM_CHAR_TRANS_SIZE);
		GX_LoadBG0Char(adr, BG_ANM_CHAR_TRANS_OFS, BG_ANM_CHAR_TRANS_SIZE);
		ptr->TrnsCount = 0;
		//転送インデックス更新
		ptr->TrnsAnmIdx = (ptr->TrnsAnmIdx+1) %  TRNS_ANM_NUM;
	}else{
		ptr->TrnsCount++;
	}
}

//----------------------------------------------------------------------------
/**
 *	@brief		画面内判定つきＳＥ再生
 *
 *	@param	inX			X座標
 *	@param	inY			Y座標
 *	@param	inSE		SE
 *	@param	inMine		自分ならTRUE
 *
 *	@return	none
 */
//-----------------------------------------------------------------------------
static void PlaySeDispCheck(const int inX, const int inY, const int inSE, const BOOL inMine)
{
	int se_player;

	if ( (0<=inX)&&(inX<256)&&
		 (0<=inY)&&(inY<192) ){
		if (inMine){
			se_player = SE_PLAYER_MINE;
		}else{
			se_player = SE_PLAYER_OTHERS;
		}
		Snd_SePlayEx( inSE, se_player );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * レコードコールバック関数
 *
 * @param	work		ポケスロンワークポインタ
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void RecCallBack(PKTHLN_PTR work)
{
	COMM_EVENT_COMMON_DATA * data;
	STL_PARENT_DATA *parent;
	PKTHLN_STL_PTR ptr;

	data = PTFrame_GetEvtComCmnData(work);
	parent = PKTHLN_CommPack_GetData(&data->ReciveShareData);
	ptr = PTFrame_GetEventWorkPtr(work);

	//ニューレコード用にレコードをセット
	{
		u16 point;
		u8 temp_point;
		u8 my_net_id;
		u16 total;

		my_net_id = PTFrameGetCurrentID(work);
		point = (parent->St1[my_net_id] >> 18) & 0x3ff;		//10ビットマスク
		temp_point = (parent->St4[my_net_id] >> 11) & 0x1f;		//5ビットマスク
		total = point + temp_point;
		if (total > POINT_MAX){
			total = POINT_MAX;
		}
		//フレームワークにニューレコードチェック用のレコード値をセット
		PTFrame_SetCheckRecord(work, total);
		SetRecordStr(ptr, total);
	}
}
